summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNadav Rotem <nrotem@apple.com>2012-12-19 07:39:08 +0000
committerNadav Rotem <nrotem@apple.com>2012-12-19 07:39:08 +0000
commit33360d8ae92e5b2a48bc83f0d0358093a61101df (patch)
tree7646c6d01cb30bb42c1c9e88f20ad8ff4e242495
parentaf14a3f20b5a7facebfa58e8ac87581b535747ce (diff)
downloadbcm5719-llvm-33360d8ae92e5b2a48bc83f0d0358093a61101df.tar.gz
bcm5719-llvm-33360d8ae92e5b2a48bc83f0d0358093a61101df.zip
After reducing the size of an operation in the DAG we zero-extend the reduced
bitwidth op back to the original size. If we reduce ANDs then this can cause an endless loop. This patch changes the ZEXT to ANY_EXTEND if the demanded bits are equal or smaller than the size of the reduced operation. llvm-svn: 170505
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp7
-rw-r--r--llvm/test/CodeGen/Generic/dag-combine-crash.ll21
2 files changed, 26 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 142411d54de..cb35d584208 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -1161,7 +1161,8 @@ TargetLowering::TargetLoweringOpt::ShrinkDemandedOp(SDValue Op,
// Search for the smallest integer type with free casts to and from
// Op's type. For expedience, just check power-of-2 integer types.
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
- unsigned SmallVTBits = BitWidth - Demanded.countLeadingZeros();
+ unsigned DemandedSize = BitWidth - Demanded.countLeadingZeros();
+ unsigned SmallVTBits = DemandedSize;
if (!isPowerOf2_32(SmallVTBits))
SmallVTBits = NextPowerOf2(SmallVTBits);
for (; SmallVTBits < BitWidth; SmallVTBits = NextPowerOf2(SmallVTBits)) {
@@ -1174,7 +1175,9 @@ TargetLowering::TargetLoweringOpt::ShrinkDemandedOp(SDValue Op,
Op.getNode()->getOperand(0)),
DAG.getNode(ISD::TRUNCATE, dl, SmallVT,
Op.getNode()->getOperand(1)));
- SDValue Z = DAG.getNode(ISD::ZERO_EXTEND, dl, Op.getValueType(), X);
+ bool NeedZext = DemandedSize > SmallVTBits;
+ SDValue Z = DAG.getNode(NeedZext ? ISD::ZERO_EXTEND : ISD::ANY_EXTEND,
+ dl, Op.getValueType(), X);
return CombineTo(Op, Z);
}
}
diff --git a/llvm/test/CodeGen/Generic/dag-combine-crash.ll b/llvm/test/CodeGen/Generic/dag-combine-crash.ll
new file mode 100644
index 00000000000..a7810b5c05e
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/dag-combine-crash.ll
@@ -0,0 +1,21 @@
+; RUN: llc < %s
+
+define void @main() {
+if.end:
+ br label %block.i.i
+
+block.i.i:
+ %tmpbb = load i8* undef
+ %tmp54 = zext i8 %tmpbb to i64
+ %tmp59 = and i64 %tmp54, 8
+ %tmp60 = add i64 %tmp59, 3691045929300498764
+ %tmp62 = sub i64 %tmp60, 3456506383779105993
+ %tmp63 = xor i64 1050774804270620004, %tmp62
+ %tmp65 = xor i64 %tmp62, 234539545521392771
+ %tmp67 = or i64 %tmp65, %tmp63
+ %tmp71 = xor i64 %tmp67, 6781485823212740913
+ %tmp72 = trunc i64 %tmp71 to i32
+ %tmp74 = lshr i32 2, %tmp72
+ store i32 %tmp74, i32* undef
+ br label %block.i.i
+}
OpenPOWER on IntegriCloud