Subtraction is not commutative. Fixes PR23212!
authorNick Lewycky <nicholas@mxc.ca>
Mon, 13 Apr 2015 19:17:37 +0000 (19:17 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Mon, 13 Apr 2015 19:17:37 +0000 (19:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234780 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineCalls.cpp
lib/Transforms/InstCombine/InstCombineCompares.cpp
test/Transforms/InstCombine/intrinsics.ll

index 8c6dc09921067a9301bbcc44a000d000f8a8dc22..11094e9939743cfaf98255ca6eb207ffc7a3b2d6 100644 (file)
@@ -416,12 +416,10 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
     }
     break;
 
-    case Intrinsic::uadd_with_overflow: // FALLTHROUGH
-    case Intrinsic::sadd_with_overflow: // FALLTHROUGH
-    case Intrinsic::usub_with_overflow: // FALLTHROUGH
-    case Intrinsic::ssub_with_overflow: // FALLTHROUGH
-    case Intrinsic::umul_with_overflow: // FALLTHROUGH
-    case Intrinsic::smul_with_overflow: {
+  case Intrinsic::uadd_with_overflow:
+  case Intrinsic::sadd_with_overflow:
+  case Intrinsic::umul_with_overflow:
+  case Intrinsic::smul_with_overflow:
     if (isa<Constant>(II->getArgOperand(0)) &&
         !isa<Constant>(II->getArgOperand(1))) {
       // Canonicalize constants into the RHS.
@@ -430,7 +428,10 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
       II->setArgOperand(1, LHS);
       return II;
     }
+    [[clang::fallthrough]];
 
+  case Intrinsic::usub_with_overflow:
+  case Intrinsic::ssub_with_overflow: {
     OverflowCheckFlavor OCF =
         IntrinsicIDToOverflowCheckFlavor(II->getIntrinsicID());
     assert(OCF != OCF_INVALID && "unexpected!");
index e084d3d8b03ba28f36b4f66a8e6ebeb9b10fe0fd..223bba03507cb221cae933205844c01274e2a79b 100644 (file)
@@ -2112,7 +2112,8 @@ static Instruction *ProcessUGT_ADDCST_ADD(ICmpInst &I, Value *A, Value *B,
 bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS,
                                          Value *RHS, Instruction &OrigI,
                                          Value *&Result, Constant *&Overflow) {
-  assert(!(isa<Constant>(LHS) && !isa<Constant>(RHS)) &&
+  assert((!OrigI.isCommutative() ||
+          !(isa<Constant>(LHS) && !isa<Constant>(RHS))) &&
          "call with a constant RHS if possible!");
 
   auto SetResult = [&](Value *OpResult, Constant *OverflowVal, bool ReuseName) {
index 539628a31be64d27ce4661c1c0d32e3d1c6bcef4..f9ccf51a621f9f3d759c31cc10d76c05cf24569b 100644 (file)
@@ -407,3 +407,13 @@ entry:
   %obit = extractvalue %ov.result.32 %t, 1
   ret i1 %obit
 }
+
+define %ov.result.32 @ssubtest_reorder(i8 %a) {
+  %A = sext i8 %a to i32
+  %x = call %ov.result.32 @llvm.ssub.with.overflow.i32(i32 0, i32 %A)
+  ret %ov.result.32 %x
+; CHECK-LABEL: @ssubtest_reorder
+; CHECK: %x = sub nsw i32 0, %A
+; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
+; CHECK-NEXT:  ret %ov.result.32 %1
+}