[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
sabre at nondot.org
Sun Apr 8 00:47:19 PDT 2007
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.732 -> 1.733
---
Log message:
Generalize the code that handles (A&B)|(A&C) to work where B/C are not constants.
Add a new xform to simplify (A&B)|(~A&C). THis implements InstCombine/or2.ll:test1
---
Diffs of the changes: (+83 -30)
InstructionCombining.cpp | 113 ++++++++++++++++++++++++++++++++++-------------
1 files changed, 83 insertions(+), 30 deletions(-)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.732 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.733
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.732 Fri Apr 6 13:57:34 2007
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sun Apr 8 02:47:01 2007
@@ -3709,36 +3709,89 @@
return BinaryOperator::createXor(NOr, C1);
}
- // (A & C1)|(B & C2)
- if (match(Op0, m_And(m_Value(A), m_ConstantInt(C1))) &&
- match(Op1, m_And(m_Value(B), m_ConstantInt(C2)))) {
-
- if (A == B) // (A & C1)|(A & C2) == A & (C1|C2)
- return BinaryOperator::createAnd(A,
- ConstantInt::get(C1->getValue() | C2->getValue()));
-
-
- // If we have: ((V + N) & C1) | (V & C2)
- // .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0
- // replace with V+N.
- if (C1->getValue() == ~C2->getValue()) {
- Value *V1 = 0, *V2 = 0;
- if ((C2->getValue() & (C2->getValue()+1)) == 0 && // C2 == 0+1+
- match(A, m_Add(m_Value(V1), m_Value(V2)))) {
- // Add commutes, try both ways.
- if (V1 == B && MaskedValueIsZero(V2, C2->getValue()))
- return ReplaceInstUsesWith(I, A);
- if (V2 == B && MaskedValueIsZero(V1, C2->getValue()))
- return ReplaceInstUsesWith(I, A);
- }
- // Or commutes, try both ways.
- if ((C1->getValue() & (C1->getValue()+1)) == 0 &&
- match(B, m_Add(m_Value(V1), m_Value(V2)))) {
- // Add commutes, try both ways.
- if (V1 == A && MaskedValueIsZero(V2, C1->getValue()))
- return ReplaceInstUsesWith(I, B);
- if (V2 == A && MaskedValueIsZero(V1, C1->getValue()))
- return ReplaceInstUsesWith(I, B);
+ // (A & C)|(B & D)
+ Value *C, *D;
+ if (match(Op0, m_And(m_Value(A), m_Value(C))) &&
+ match(Op1, m_And(m_Value(B), m_Value(D)))) {
+
+ // Check to see if we have any common things being and'ed. If so, find the
+ // terms for V1 & (V2|V3).
+ Value *V1 = 0, *V2 = 0, *V3 = 0;
+ if (isOnlyUse(Op0) || isOnlyUse(Op1)) {
+ if (A == B) // (A & C)|(A & D) == A & (C|D)
+ V1 = A, V2 = C, V3 = D;
+ else if (A == D) // (A & C)|(B & A) == A & (B|C)
+ V1 = A, V2 = B, V3 = C;
+ else if (C == B) // (A & C)|(C & D) == C & (A|D)
+ V1 = C, V2 = A, V3 = D;
+ else if (C == D) // (A & C)|(B & C) == C & (A|B)
+ V1 = C, V2 = A, V3 = B;
+
+ if (V1) {
+ Value *Or =
+ InsertNewInstBefore(BinaryOperator::createOr(V2, V3, "tmp"), I);
+ return BinaryOperator::createAnd(V1, Or);
+ }
+
+ // (V1 & V3)|(V2 & ~V3) -> ((V1 ^ V2) & V3) ^ V2
+ if (isOnlyUse(Op0) && isOnlyUse(Op1)) {
+ // Try all combination of terms to find V3 and ~V3.
+ if (A->hasOneUse() && match(A, m_Not(m_Value(V3)))) {
+ if (V3 == B)
+ V1 = D, V2 = C;
+ else if (V3 == D)
+ V1 = B, V2 = C;
+ }
+ if (B->hasOneUse() && match(B, m_Not(m_Value(V3)))) {
+ if (V3 == A)
+ V1 = C, V2 = D;
+ else if (V3 == C)
+ V1 = A, V2 = D;
+ }
+ if (C->hasOneUse() && match(C, m_Not(m_Value(V3)))) {
+ if (V3 == B)
+ V1 = D, V2 = A;
+ else if (V3 == D)
+ V1 = B, V2 = A;
+ }
+ if (D->hasOneUse() && match(D, m_Not(m_Value(V3)))) {
+ if (V3 == A)
+ V1 = C, V2 = B;
+ else if (V3 == C)
+ V1 = A, V2 = B;
+ }
+ if (V1) {
+ A = InsertNewInstBefore(BinaryOperator::createXor(V1, V2, "tmp"), I);
+ A = InsertNewInstBefore(BinaryOperator::createAnd(A, V3, "tmp"), I);
+ return BinaryOperator::createXor(A, V2);
+ }
+ }
+ }
+
+ C1 = dyn_cast<ConstantInt>(C);
+ C2 = dyn_cast<ConstantInt>(D);
+ if (C1 && C2) { // (A & C1)|(B & C2)
+ // If we have: ((V + N) & C1) | (V & C2)
+ // .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0
+ // replace with V+N.
+ if (C1->getValue() == ~C2->getValue()) {
+ if ((C2->getValue() & (C2->getValue()+1)) == 0 && // C2 == 0+1+
+ match(A, m_Add(m_Value(V1), m_Value(V2)))) {
+ // Add commutes, try both ways.
+ if (V1 == B && MaskedValueIsZero(V2, C2->getValue()))
+ return ReplaceInstUsesWith(I, A);
+ if (V2 == B && MaskedValueIsZero(V1, C2->getValue()))
+ return ReplaceInstUsesWith(I, A);
+ }
+ // Or commutes, try both ways.
+ if ((C1->getValue() & (C1->getValue()+1)) == 0 &&
+ match(B, m_Add(m_Value(V1), m_Value(V2)))) {
+ // Add commutes, try both ways.
+ if (V1 == A && MaskedValueIsZero(V2, C1->getValue()))
+ return ReplaceInstUsesWith(I, B);
+ if (V2 == A && MaskedValueIsZero(V1, C1->getValue()))
+ return ReplaceInstUsesWith(I, B);
+ }
}
}
}
More information about the llvm-commits
mailing list