From: Chris Lattner Date: Sun, 19 Dec 2010 19:35:32 +0000 (+0000) Subject: optimize uadd(x, cst) into a comparison when the normal X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=26b482d7a76df3f67675ce852daed0eba709c63e;p=oota-llvm.git optimize uadd(x, cst) into a comparison when the normal 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 --- diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index d53f3291e71..f3a5e724c61 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -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(RHS)) + if (ExtractValueInst *EVI = dyn_cast(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: diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll index d672d8c1535..ed9c7b3840a 100644 --- a/test/Transforms/InstCombine/intrinsics.ll +++ b/test/Transforms/InstCombine/intrinsics.ll @@ -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