From 0036e3a4698d947c455e755faafe5c83a9c3b9c6 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 11 Oct 2009 21:22:21 +0000 Subject: [PATCH] simplify a transformation by making it more general. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83792 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 46 ++++++------------- test/Transforms/InstCombine/icmp.ll | 10 +++- test/Transforms/InstCombine/mul.ll | 11 +++++ 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 06a5660f72e..e9ffb730305 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -2783,39 +2783,21 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) { // we know the bool is either zero or one, so this is a 'masking' multiply. // See if we can simplify things based on how the boolean was originally // formed. - CastInst *BoolCast = 0; - if (ZExtInst *CI = dyn_cast(Op0)) - if (CI->getOperand(0)->getType() == Type::getInt1Ty(*Context)) - BoolCast = CI; - if (!BoolCast) - if (ZExtInst *CI = dyn_cast(I.getOperand(1))) + { + Value *BoolCast = 0, *OtherOp = 0; + if (ZExtInst *CI = dyn_cast(Op0)) if (CI->getOperand(0)->getType() == Type::getInt1Ty(*Context)) - BoolCast = CI; - if (BoolCast) { - if (ICmpInst *SCI = dyn_cast(BoolCast->getOperand(0))) { - Value *SCIOp0 = SCI->getOperand(0), *SCIOp1 = SCI->getOperand(1); - const Type *SCOpTy = SCIOp0->getType(); - bool TIS = false; - - // If the icmp is true iff the sign bit of X is set, then convert this - // multiply into a shift/and combination. - if (isa(SCIOp1) && - isSignBitCheck(SCI->getPredicate(), cast(SCIOp1), TIS) && - TIS) { - // Shift the X value right to turn it into "all signbits". - Constant *Amt = ConstantInt::get(SCIOp0->getType(), - SCOpTy->getPrimitiveSizeInBits()-1); - Value *V = Builder->CreateAShr(SCIOp0, Amt, - BoolCast->getOperand(0)->getName()+".mask"); - - // If the multiply type is not the same as the source type, sign extend - // or truncate to the multiply type. - if (I.getType() != V->getType()) - V = Builder->CreateIntCast(V, I.getType(), true); - - Value *OtherOp = Op0 == BoolCast ? I.getOperand(1) : Op0; - return BinaryOperator::CreateAnd(V, OtherOp); - } + BoolCast = CI, OtherOp = I.getOperand(1); + if (!BoolCast) + if (ZExtInst *CI = dyn_cast(I.getOperand(1))) + if (CI->getOperand(0)->getType() == Type::getInt1Ty(*Context)) + BoolCast = CI, OtherOp = Op0; + + if (BoolCast) { + // X * Y (where Y is 0 or 1) -> X & (0-Y) + Value *V = Builder->CreateSub(Constant::getNullValue(I.getType()), + BoolCast, "tmp"); + return BinaryOperator::CreateAnd(V, OtherOp); } } diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index 3b6f8c59ce6..64e88c9ae86 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -33,4 +33,12 @@ define <2 x i1> @test5(<2 x i64> %x) { entry: %V = icmp eq <2 x i64> %x, undef ret <2 x i1> %V -} \ No newline at end of file +} + +define i32 @test6(i32 %a, i32 %b) { + %c = icmp sle i32 %a, -1 + %d = zext i1 %c to i32 + %e = sub i32 0, %d + %f = and i32 %e, %b + ret i32 %f +} diff --git a/test/Transforms/InstCombine/mul.ll b/test/Transforms/InstCombine/mul.ll index e127efb9dcf..d8e623c4834 100644 --- a/test/Transforms/InstCombine/mul.ll +++ b/test/Transforms/InstCombine/mul.ll @@ -96,3 +96,14 @@ entry: %m = mul i32 %shl, %A ret i32 %m } + +; X * Y (when Y is 0 or 1) --> x & (0-Y) +define i32 @test16(i32 %b, i1 %c) { + %d = zext i1 %c to i32 ; [#uses=1] + ; e = b & (a >> 31) + %e = mul i32 %d, %b ; [#uses=1] + ret i32 %e +} + + +