[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp

Chris Lattner lattner at cs.uiuc.edu
Sat Sep 17 20:42:18 PDT 2005



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.371 -> 1.372
---
Log message:

Implement or.ll:test21.  This teaches instcombine to be able to turn this:

struct {
   unsigned int bit0:1;
   unsigned int ubyte:31;
} sdata;

void foo() {
  sdata.ubyte++;
}

into this:

foo:
        add DWORD PTR [sdata], 2
        ret

instead of this:

foo:
        mov %EAX, DWORD PTR [sdata]
        mov %ECX, %EAX
        add %ECX, 2
        and %ECX, -2
        and %EAX, 1
        or %EAX, %ECX
        mov DWORD PTR [sdata], %EAX
        ret




---
Diffs of the changes:  (+25 -3)

 InstructionCombining.cpp |   28 +++++++++++++++++++++++++---
 1 files changed, 25 insertions(+), 3 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.371 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.372
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.371	Wed Sep 14 12:32:56 2005
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Sat Sep 17 22:42:07 2005
@@ -1921,10 +1921,31 @@
     return BinaryOperator::createXor(InsertNewInstBefore(NOr, I), C1);
   }
 
-  // (A & C1)|(A & C2) == A & (C1|C2)
+  // (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))) && A == B)
-    return BinaryOperator::createAnd(A, ConstantExpr::getOr(C1, C2));
+      match(Op1, m_And(m_Value(B), m_ConstantInt(C2)))) {
+
+    if (A == B)  // (A & C1)|(A & C2) == A & (C1|C2)
+      return BinaryOperator::createAnd(A, ConstantExpr::getOr(C1, C2));
+
+
+    // if A == (add B, C3)  or B == (add A, C4)
+    ConstantInt *C3 = 0;
+    Value *V = 0;
+    if ((match(A, m_Add(m_Value(V), m_ConstantInt(C3))) && V == B ||
+         match(B, m_Add(m_Value(V), m_ConstantInt(C3))) && V == A)) {
+      if (V == A) std::swap(C1, C2);
+      // We have: ((V + C3) & C1) | (V & C2)
+      // if C2 = ~C1 and (C3 & C2) == 0 and C2 is 0+1+
+      if (C1 == ConstantExpr::getNot(C2) &&
+          ConstantExpr::getAnd(C3, C2)->isNullValue() &&
+          (C2->getRawValue() & (C2->getRawValue()+1)) == 0) {
+        // Return V+C3.
+        std::cerr << "Simpl: " << *A << "Simpl2: " << *B << "Simpl3: " << I;
+        return ReplaceInstUsesWith(I, V == A ? B : A);
+      }
+    }
+  }
 
   if (match(Op0, m_Not(m_Value(A)))) {   // ~A | Op1
     if (A == Op1)   // ~A | A == -1
@@ -2040,6 +2061,7 @@
           }
         }
   }
+
   return Changed ? &I : 0;
 }
 






More information about the llvm-commits mailing list