aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-05-19 20:01:56 +0000
committerChris Lattner <sabre@nondot.org>2008-05-19 20:01:56 +0000
commit5e0d71877c35030fd184ec2cbe0a0aaaa383cd71 (patch)
tree56a9ef2621bdc0a0e85850adc1170eb4c9c321d9
parent1e6a575a8f0a27095927df7951a29174328a8b56 (diff)
downloadexternal_llvm-5e0d71877c35030fd184ec2cbe0a0aaaa383cd71.zip
external_llvm-5e0d71877c35030fd184ec2cbe0a0aaaa383cd71.tar.gz
external_llvm-5e0d71877c35030fd184ec2cbe0a0aaaa383cd71.tar.bz2
be more aggressive about transforming add -> or when the operands have no
intersecting bits. This triggers all over the place, for example in lencode, with adds of stuff like: %tmp580 = mul i32 %tmp579, 2 %tmp582 = and i32 %b8, 1 and %tmp28 = shl i32 %abs.i, 1 %sign.0 = select i1 %tmp23, i32 1, i32 0 and %tmp344 = shl i32 %tmp343, 2 %tmp346 = and i32 %tmp96, 3 etc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51263 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp19
-rw-r--r--test/Transforms/InstCombine/add2.ll15
2 files changed, 34 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 8c5e136..3b34124 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -2503,6 +2503,25 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
if (match(RHS, m_And(m_Value(), m_ConstantInt(C2))))
if (Instruction *R = AssociativeOpt(I, AddMaskingAnd(C2)))
return R;
+
+ // A+B --> A|B iff A and B have no bits set in common.
+ if (const IntegerType *IT = dyn_cast<IntegerType>(I.getType())) {
+ APInt Mask = APInt::getAllOnesValue(IT->getBitWidth());
+ APInt LHSKnownOne(IT->getBitWidth(), 0);
+ APInt LHSKnownZero(IT->getBitWidth(), 0);
+ ComputeMaskedBits(LHS, Mask, LHSKnownZero, LHSKnownOne);
+ if (LHSKnownZero != 0) {
+ APInt RHSKnownOne(IT->getBitWidth(), 0);
+ APInt RHSKnownZero(IT->getBitWidth(), 0);
+ ComputeMaskedBits(RHS, Mask, RHSKnownZero, RHSKnownOne);
+
+ // No bits in common -> bitwise or.
+ if ((LHSKnownZero|RHSKnownZero).isAllOnesValue()) {
+ cerr << "HACK\n" << *LHS << *RHS << "\n";
+ return BinaryOperator::CreateOr(LHS, RHS);
+ }
+ }
+ }
// W*X + Y*Z --> W * (X+Z) iff W == Y
if (I.getType()->isIntOrIntVector()) {
diff --git a/test/Transforms/InstCombine/add2.ll b/test/Transforms/InstCombine/add2.ll
index de1bbf4..161d56b 100644
--- a/test/Transforms/InstCombine/add2.ll
+++ b/test/Transforms/InstCombine/add2.ll
@@ -29,3 +29,18 @@ EntryBlock:
declare i32 @callee(i32)
+
+define i32 @test3(i32 %A) {
+ %B = and i32 %A, 7
+ %C = and i32 %A, 32
+ %F = add i32 %B, %C
+ ret i32 %F
+}
+
+define i32 @test4(i32 %A) {
+ %B = and i32 %A, 128
+ %C = lshr i32 %A, 30
+ %F = add i32 %B, %C
+ ret i32 %F
+}
+