From: Sanjay Patel Date: Mon, 31 Oct 2016 23:28:45 +0000 (+0000) Subject: [DAG] disable nsw/nuw for add/sub/mul when simplifying based on demanded bits (PR30841) X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=70c5f02d25d29b1330b2747352994812d802aeaf;p=platform%2Fupstream%2Fllvm.git [DAG] disable nsw/nuw for add/sub/mul when simplifying based on demanded bits (PR30841) This bug was exposed by using nsw/nuw for more aggressive folds in: https://reviews.llvm.org/rL284844 The changes mimic the IR demanded bits logic in InstCombiner::SimplifyDemandedUseBits(), but we can't just flip flag bits in the DAG; we have to create a new node that has the bits cleared. This should fix: https://llvm.org/bugs/show_bug.cgi?id=30841 llvm-svn: 285656 --- diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 1228298..487af80 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 0000000..f5bffb2 --- /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 %AL %EAX +; 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 +} +