OSDN Git Service

optimize uadd(x, cst) into a comparison when the normal
authorChris Lattner <sabre@nondot.org>
Sun, 19 Dec 2010 19:35:32 +0000 (19:35 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 19 Dec 2010 19:35:32 +0000 (19:35 +0000)
result is dead.  This is required for my next patch to not
regress the testsuite.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122181 91177308-0d34-0410-b5e6-96231b3b80d8

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

index d53f329..f3a5e72 100644 (file)
@@ -523,6 +523,21 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
         return InsertValueInst::Create(Struct, Add, 0);
       }
     }
+    
+    // If the normal result of the add is dead, and the RHS is a constant, we
+    // can transform this into a range comparison.
+    // overflow = uadd a, -4  -->  overflow = icmp ugt a, 3
+    if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
+      if (ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(II->use_back()))
+        if (II->hasOneUse() && EVI->getNumIndices() == 1 && !EVI->use_empty() &&
+            *EVI->idx_begin() == 1) {  // Extract of overflow result.
+          Builder->SetInsertPoint(EVI);
+          Value *R = Builder->CreateICmpUGT(LHS, ConstantExpr::getNot(CI));
+          R->takeName(EVI);
+          ReplaceInstUsesWith(*EVI, R);
+          return II;
+        }
+    
   }
   // FALL THROUGH uadd into sadd
   case Intrinsic::sadd_with_overflow:
@@ -550,6 +565,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
         return InsertValueInst::Create(Struct, II->getArgOperand(0), 0);
       }
     }
+      
     break;
   case Intrinsic::usub_with_overflow:
   case Intrinsic::ssub_with_overflow:
index d672d8c..ed9c7b3 100644 (file)
@@ -71,6 +71,16 @@ define i8 @uaddtest5(i8 %A, i1* %overflowPtr) {
 ; CHECK: ret i8 %A
 }
 
+define i1 @uaddtest6(i8 %A, i8 %B) {
+  %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %A, i8 -4)
+  %z = extractvalue %overflow.result %x, 1
+  ret i1 %z
+; CHECK: @uaddtest6
+; CHECK-NEXT: %z = icmp ugt i8 %A, 3
+; CHECK-NEXT: ret i1 %z
+}
+
+
 define i8 @umultest1(i8 %A, i1* %overflowPtr) {
   %x = call %overflow.result @llvm.umul.with.overflow.i8(i8 0, i8 %A)
   %y = extractvalue %overflow.result %x, 0