summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-10-11 21:29:45 +0000
committerChris Lattner <sabre@nondot.org>2009-10-11 21:29:45 +0000
commitfd27f8a5b38e8a2771db58b8b52843d13bc0cef0 (patch)
tree58772170a1a9653db4b9de839e3ed0c7f4bd35ca
parent2295f31810df1ed2dbaf818f2dcba4783bbc68bc (diff)
downloadbcm5719-llvm-fd27f8a5b38e8a2771db58b8b52843d13bc0cef0.tar.gz
bcm5719-llvm-fd27f8a5b38e8a2771db58b8b52843d13bc0cef0.zip
generalize a transformation even more: we don't care whether the
input the the mul is a zext from bool, just that it is all zeros other than the low bit. This fixes some phase ordering issues that would cause us to miss some xforms in mul.ll when the worklist is visited differently. llvm-svn: 83794
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp22
-rw-r--r--llvm/test/Transforms/InstCombine/mul.ll7
2 files changed, 17 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index e9ffb730305..549c57633a4 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -2781,20 +2781,18 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
// If one of the operands of the multiply is a cast from a boolean value, then
// 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.
- {
- Value *BoolCast = 0, *OtherOp = 0;
- if (ZExtInst *CI = dyn_cast<ZExtInst>(Op0))
- if (CI->getOperand(0)->getType() == Type::getInt1Ty(*Context))
- BoolCast = CI, OtherOp = I.getOperand(1);
- if (!BoolCast)
- if (ZExtInst *CI = dyn_cast<ZExtInst>(I.getOperand(1)))
- if (CI->getOperand(0)->getType() == Type::getInt1Ty(*Context))
- BoolCast = CI, OtherOp = Op0;
+ // X * Y (where Y is 0 or 1) -> X & (0-Y)
+ if (!isa<VectorType>(I.getType())) {
+ // -2 is "-1 << 1" so it is all bits set except the low one.
+ APInt Negative2(I.getType()->getPrimitiveSizeInBits(), -2, true);
+ Value *BoolCast = 0, *OtherOp = 0;
+ if (MaskedValueIsZero(Op0, Negative2))
+ BoolCast = Op0, OtherOp = I.getOperand(1);
+ else if (MaskedValueIsZero(I.getOperand(1), Negative2))
+ BoolCast = I.getOperand(1), 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/llvm/test/Transforms/InstCombine/mul.ll b/llvm/test/Transforms/InstCombine/mul.ll
index d8e623c4834..53a56434aed 100644
--- a/llvm/test/Transforms/InstCombine/mul.ll
+++ b/llvm/test/Transforms/InstCombine/mul.ll
@@ -105,5 +105,12 @@ define i32 @test16(i32 %b, i1 %c) {
ret i32 %e
}
+; X * Y (when Y is 0 or 1) --> x & (0-Y)
+define i32 @test17(i32 %a, i32 %b) {
+ %a.lobit = lshr i32 %a, 31
+ %e = mul i32 %a.lobit, %b
+ ret i32 %e
+}
+
OpenPOWER on IntegriCloud