diff options
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 25 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/add-sub-nsw-nuw.ll | 25 |
2 files changed, 43 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 12282988129..487af807ab9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1216,14 +1216,25 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, APInt LoMask = APInt::getLowBitsSet(BitWidth, BitWidth - NewMask.countLeadingZeros()); if (SimplifyDemandedBits(Op.getOperand(0), LoMask, KnownZero2, - KnownOne2, TLO, Depth+1)) - return true; - if (SimplifyDemandedBits(Op.getOperand(1), LoMask, KnownZero2, - KnownOne2, TLO, Depth+1)) - return true; - // See if the operation should be performed at a smaller bit width. - if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl)) + KnownOne2, TLO, Depth+1) || + SimplifyDemandedBits(Op.getOperand(1), LoMask, KnownZero2, + KnownOne2, TLO, Depth+1) || + // See if the operation should be performed at a smaller bit width. + TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl)) { + const SDNodeFlags *Flags = Op.getNode()->getFlags(); + if (Flags->hasNoSignedWrap() || Flags->hasNoUnsignedWrap()) { + // Disable the nsw and nuw flags. We can no longer guarantee that we + // won't wrap after simplification. + SDNodeFlags NewFlags = *Flags; + NewFlags.setNoSignedWrap(false); + NewFlags.setNoUnsignedWrap(false); + SDValue NewOp = TLO.DAG.getNode(Op.getOpcode(), dl, Op.getValueType(), + Op.getOperand(0), Op.getOperand(1), + &NewFlags); + return TLO.CombineTo(Op, NewOp); + } return true; + } LLVM_FALLTHROUGH; } default: diff --git a/llvm/test/CodeGen/X86/add-sub-nsw-nuw.ll b/llvm/test/CodeGen/X86/add-sub-nsw-nuw.ll new file mode 100644 index 00000000000..f5bffb2386b --- /dev/null +++ b/llvm/test/CodeGen/X86/add-sub-nsw-nuw.ll @@ -0,0 +1,25 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: llc -mtriple=i386-apple-darwin < %s | FileCheck %s + +; PR30841: https://llvm.org/bugs/show_bug.cgi?id=30841 +; Demanded bits analysis must disable nsw/nuw when it makes a +; simplification to add/sub such as in this case. + +define i8 @PR30841(i64 %argc) { +; CHECK-LABEL: PR30841: +; CHECK: ## BB#0: ## %entry +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax +; CHECK-NEXT: negl %eax +; CHECK-NEXT: ## kill: %AL<def> %AL<kill> %EAX<kill> +; CHECK-NEXT: retl +; +entry: + %or = or i64 %argc, -4294967296 + br label %end + +end: + %neg = sub nuw nsw i64 -4294967296, %argc + %trunc = trunc i64 %neg to i8 + ret i8 %trunc +} + |