diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index ce9ce3aeb5f..317a41a05f4 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -3476,8 +3476,9 @@ static SDValue PerformORCombine(SDNode *N, BuildVectorSDNode *BVN1 = dyn_cast(N1->getOperand(1)); APInt SplatBits1; if (BVN1 && BVN1->isConstantSplat(SplatBits1, SplatUndef, SplatBitSize, - HasAnyUndefs) && - !HasAnyUndefs && SplatBits0 == ~SplatBits1) { + HasAnyUndefs) && !HasAnyUndefs && + SplatBits0.getBitWidth() == SplatBits1.getBitWidth() && + SplatBits0 == ~SplatBits1) { return DAG.getNode(ISD::VSELECT, DL, VT, N0->getOperand(1), N0->getOperand(0), N1->getOperand(0)); diff --git a/test/CodeGen/AArch64/neon-or-combine.ll b/test/CodeGen/AArch64/neon-or-combine.ll new file mode 100644 index 00000000000..260f6935dde --- /dev/null +++ b/test/CodeGen/AArch64/neon-or-combine.ll @@ -0,0 +1,29 @@ +; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon | FileCheck %s + +; Check that the DAGCombiner does not crash with an assertion failure +; when performing a target specific combine to simplify a 'or' dag node +; according to the following rule: +; (or (and B, A), (and C, ~A)) => (VBSL A, B, C) +; The assertion failure was caused by an invalid comparison between APInt +; values with different 'BitWidth'. + +define <8 x i8> @test1(<8 x i8> %a, <8 x i8> %b) { + %tmp1 = and <8 x i8> %a, < i8 -1, i8 -1, i8 0, i8 0, i8 -1, i8 -1, i8 0, i8 0 > + %tmp2 = and <8 x i8> %b, < i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0 > + %tmp3 = or <8 x i8> %tmp1, %tmp2 + ret <8 x i8> %tmp3 +} + +; CHECK-LABEL: test1 +; CHECK: ret + +define <16 x i8> @test2(<16 x i8> %a, <16 x i8> %b) { + %tmp1 = and <16 x i8> %a, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1 > + %tmp2 = and <16 x i8> %b, < i8 -1, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0 > + %tmp3 = or <16 x i8> %tmp1, %tmp2 + ret <16 x i8> %tmp3 +} + +; CHECK-LABEL: test2 +; CHECK: ret +