diff options
author | Chris Lattner <sabre@nondot.org> | 2008-05-19 20:01:56 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-05-19 20:01:56 +0000 |
commit | 5e0d71877c35030fd184ec2cbe0a0aaaa383cd71 (patch) | |
tree | 56a9ef2621bdc0a0e85850adc1170eb4c9c321d9 | |
parent | 1e6a575a8f0a27095927df7951a29174328a8b56 (diff) | |
download | external_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.cpp | 19 | ||||
-rw-r--r-- | test/Transforms/InstCombine/add2.ll | 15 |
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 +} + |