diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 142411d54ded..cb35d5842084 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 000000000000..a7810b5c05e2 --- /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 +}