summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2014-01-13 16:51:00 +0000
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2014-01-13 16:51:00 +0000
commit9bc0415c1fd937bdbc7d87bb7486b83c0aab32c9 (patch)
tree81c8dda23de55ca91376b7b681e8e5af37ad0768
parent808df6725f29297a386725ec4e89835112f9b703 (diff)
downloadbcm5719-llvm-9bc0415c1fd937bdbc7d87bb7486b83c0aab32c9.tar.gz
bcm5719-llvm-9bc0415c1fd937bdbc7d87bb7486b83c0aab32c9.zip
[AArch64] Fix assertion failure caused by an invalid comparison between APInt values.
APInt only knows how to compare values with the same BitWidth and asserts in all other cases. With this fix, function PerformORCombine does not use the APInt equality operator if the APInt values returned by 'isConstantSplat' differ in BitWidth. In that case they are different and no comparison is needed. llvm-svn: 199119
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.cpp5
-rw-r--r--llvm/test/CodeGen/AArch64/neon-or-combine.ll29
2 files changed, 32 insertions, 2 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index ce9ce3aeb5f..317a41a05f4 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -3476,8 +3476,9 @@ static SDValue PerformORCombine(SDNode *N,
BuildVectorSDNode *BVN1 = dyn_cast<BuildVectorSDNode>(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/llvm/test/CodeGen/AArch64/neon-or-combine.ll b/llvm/test/CodeGen/AArch64/neon-or-combine.ll
new file mode 100644
index 00000000000..260f6935dde
--- /dev/null
+++ b/llvm/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
+
OpenPOWER on IntegriCloud