diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2011-05-21 09:22:06 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2011-05-21 09:22:06 +0000 |
commit | c21b205f93fa7bc135928ff9f4981f9062e2fd53 (patch) | |
tree | a31226f2764d92e5252370b829603901aff5cba4 | |
parent | 37fed38ec155705803250273467d5bec66e0dcd5 (diff) | |
download | external_llvm-c21b205f93fa7bc135928ff9f4981f9062e2fd53.zip external_llvm-c21b205f93fa7bc135928ff9f4981f9062e2fd53.tar.gz external_llvm-c21b205f93fa7bc135928ff9f4981f9062e2fd53.tar.bz2 |
InstCombine: Turn mul.with.overflow(X, 2) into the cheaper add.with.overflow(X, X)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131789 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineCalls.cpp | 14 | ||||
-rw-r--r-- | test/Transforms/InstCombine/intrinsics.ll | 21 |
2 files changed, 35 insertions, 0 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index 2439377..ea0ffd9 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -535,6 +535,20 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { Constant *Struct = ConstantStruct::get(II->getContext(), V, 2, false); return InsertValueInst::Create(Struct, II->getArgOperand(0), 0); } + + // [su]mul.with.overflow(X, 2) -> [su]add.with.overflow(X, X) + if (RHSI->equalsInt(2)) { + Intrinsic::ID Add = + II->getIntrinsicID() == Intrinsic::smul_with_overflow ? + Intrinsic::sadd_with_overflow : Intrinsic::uadd_with_overflow; + + Module *M = II->getParent()->getParent()->getParent(); + const Type *Ty = RHSI->getType(); + Function *F = Intrinsic::getDeclaration(M, Add, &Ty, 1); + + Value *Ops[] = { II->getArgOperand(0), II->getArgOperand(0) }; + return CallInst::Create(F, Ops, Ops+2); + } } break; case Intrinsic::ppc_altivec_lvx: diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll index 107f313..3a0b312 100644 --- a/test/Transforms/InstCombine/intrinsics.ll +++ b/test/Transforms/InstCombine/intrinsics.ll @@ -114,6 +114,7 @@ define i8 @umultest2(i8 %A, i1* %overflowPtr) { %ov.result.32 = type { i32, i1 } declare %ov.result.32 @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone +declare %ov.result.32 @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone define i32 @umultest3(i32 %n) nounwind { %shr = lshr i32 %n, 2 @@ -139,6 +140,26 @@ define i32 @umultest4(i32 %n) nounwind { ; CHECK: umul.with.overflow } +define i32 @umultest5(i32 %n) nounwind { + %mul = call %ov.result.32 @llvm.umul.with.overflow.i32(i32 %n, i32 2) + %ov = extractvalue %ov.result.32 %mul, 1 + %res = extractvalue %ov.result.32 %mul, 0 + %ret = select i1 %ov, i32 -1, i32 %res + ret i32 %ret +; CHECK: @umultest5 +; CHECK: llvm.uadd.with.overflow.i32(i32 %n, i32 %n) +} + +define i32 @smultest1(i32 %n) nounwind { + %mul = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %n, i32 2) + %ov = extractvalue %ov.result.32 %mul, 1 + %res = extractvalue %ov.result.32 %mul, 0 + %ret = select i1 %ov, i32 -1, i32 %res + ret i32 %ret +; CHECK: @smultest1 +; CHECK: llvm.sadd.with.overflow.i32(i32 %n, i32 %n) +} + define void @powi(double %V, double *%P) { entry: %A = tail call double @llvm.powi.f64(double %V, i32 -1) nounwind |