summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorDaniel Sanders <daniel.sanders@imgtec.com>2013-11-21 16:11:31 +0000
committerDaniel Sanders <daniel.sanders@imgtec.com>2013-11-21 16:11:31 +0000
commitc8c50fb41fb030b3a643fce4995d7e6434f5af12 (patch)
treea8de329b618b88f2a667c95c841e1e378bbce872 /llvm
parent534140425816613454de75728d50715ec5ec034b (diff)
downloadbcm5719-llvm-c8c50fb41fb030b3a643fce4995d7e6434f5af12.tar.gz
bcm5719-llvm-c8c50fb41fb030b3a643fce4995d7e6434f5af12.zip
[mips][msa] Fix a corner case in performORCombine() when combining nodes into VSELECT.
Mask == ~InvMask asserts if the width of Mask and InvMask differ. The combine isn't valid (with two exceptions, see below) if the widths differ so test for this before testing Mask == ~InvMask. In the specific cases of Mask=~0 and InvMask=0, as well as Mask=0 and InvMask=~0, the combine is still valid. However, there are more appropriate combines that could be used in these cases such as folding x & 0 to 0, or x & ~0 to x. llvm-svn: 195364
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelLowering.cpp12
-rw-r--r--llvm/test/CodeGen/Mips/msa/llvm-stress-s449609655-simplified.ll33
2 files changed, 41 insertions, 4 deletions
diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
index 274cdc1f89a..27d7515c40c 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -594,9 +594,11 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
Cond = Op0Op0;
IfSet = Op0Op1;
- if (isVSplat(Op1Op0, InvMask, IsLittleEndian) && Mask == ~InvMask)
+ if (isVSplat(Op1Op0, InvMask, IsLittleEndian) &&
+ Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
IfClr = Op1Op1;
- else if (isVSplat(Op1Op1, InvMask, IsLittleEndian) && Mask == ~InvMask)
+ else if (isVSplat(Op1Op1, InvMask, IsLittleEndian) &&
+ Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
IfClr = Op1Op0;
IsConstantMask = true;
@@ -609,9 +611,11 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
Cond = Op0Op1;
IfSet = Op0Op0;
- if (isVSplat(Op1Op0, InvMask, IsLittleEndian) && Mask == ~InvMask)
+ if (isVSplat(Op1Op0, InvMask, IsLittleEndian) &&
+ Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
IfClr = Op1Op1;
- else if (isVSplat(Op1Op1, InvMask, IsLittleEndian) && Mask == ~InvMask)
+ else if (isVSplat(Op1Op1, InvMask, IsLittleEndian) &&
+ Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
IfClr = Op1Op0;
IsConstantMask = true;
diff --git a/llvm/test/CodeGen/Mips/msa/llvm-stress-s449609655-simplified.ll b/llvm/test/CodeGen/Mips/msa/llvm-stress-s449609655-simplified.ll
new file mode 100644
index 00000000000..24e27cbf14b
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/msa/llvm-stress-s449609655-simplified.ll
@@ -0,0 +1,33 @@
+; RUN: llc -march=mips < %s
+; RUN: llc -march=mips -mattr=+msa,+fp64 < %s
+; RUN: llc -march=mipsel < %s
+; RUN: llc -march=mipsel -mattr=+msa,+fp64 < %s
+
+; This test is based on an llvm-stress generated test case with seed=449609655
+
+; This test originally failed for MSA with a
+; "Comparison requires equal bit widths" assertion.
+; The legalizer legalized ; the <4 x i8>'s into <4 x i32>'s, then a call to
+; isVSplat() returned the splat value for <i8 -1, i8 -1, ...> as a 32-bit APInt
+; (255), but the zeroinitializer splat value as an 8-bit APInt (0). The
+; assertion occured when trying to check the values were bitwise inverses of
+; each-other.
+;
+; It should at least successfully build.
+
+define void @autogen_SD449609655(i8) {
+BB:
+ %Cmp = icmp ult i8 -3, %0
+ br label %CF78
+
+CF78: ; preds = %CF81, %CF78, %BB
+ %Sl31 = select i1 %Cmp, <4 x i8> <i8 -1, i8 -1, i8 -1, i8 -1>, <4 x i8> zeroinitializer
+ br i1 undef, label %CF78, label %CF81
+
+CF81: ; preds = %CF78
+ br i1 undef, label %CF78, label %CF80
+
+CF80: ; preds = %CF81
+ %I59 = insertelement <4 x i8> %Sl31, i8 undef, i32 1
+ ret void
+}
OpenPOWER on IntegriCloud