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

Chris Lattner lattner at cs.uiuc.edu
Sat Sep 17 23:31:10 PDT 2005



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.378 -> 1.379
---
Log message:

Compile 
struct S { unsigned int i : 6, j : 11, k : 15; } b;
void plus2 (unsigned int x) {
  b.j += x;
}

to:

plus2:
        mov %EAX, DWORD PTR [b]
        mov %ECX, %EAX
        and %ECX, 131008
        mov %EDX, DWORD PTR [%ESP + 4]
        shl %EDX, 6
        add %EDX, %ECX
        and %EDX, 131008
        and %EAX, -131009
        or %EDX, %EAX
        mov DWORD PTR [b], %EDX
        ret

instead of:

plus2:
        mov %EAX, DWORD PTR [b]
        mov %ECX, %EAX
        shr %ECX, 6
        and %ECX, 2047
        add %ECX, DWORD PTR [%ESP + 4]
        shl %ECX, 6
        and %ECX, 131008
        and %EAX, -131009
        or %ECX, %EAX
        mov DWORD PTR [b], %ECX
        ret



---
Diffs of the changes:  (+70 -31)

 InstructionCombining.cpp |  101 ++++++++++++++++++++++++++++++++---------------
 1 files changed, 70 insertions(+), 31 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.378 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.379
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.378	Sun Sep 18 01:02:59 2005
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Sun Sep 18 01:30:59 2005
@@ -3364,6 +3364,8 @@
 
       if (BinaryOperator *Op0BO = dyn_cast<BinaryOperator>(Op0)) {
         // Turn ((X >> C) + Y) << C  ->  (X + (Y << C)) & (~0 << C)
+        Value *V1, *V2, *V3;
+        ConstantInt *CC;
         switch (Op0BO->getOpcode()) {
         default: break;
         case Instruction::Add:
@@ -3372,39 +3374,76 @@
         case Instruction::Xor:
           // These operators commute.
           // Turn (Y + (X >> C)) << C  ->  (X + (Y << C)) & (~0 << C)
-          if (ShiftInst *XS = dyn_cast<ShiftInst>(Op0BO->getOperand(1)))
-            if (isLeftShift && XS->hasOneUse() && XS->getOperand(1) == CUI &&
-                XS->getOpcode() == Instruction::Shr) {
-              Instruction *YS = new ShiftInst(Instruction::Shl, 
-                                              Op0BO->getOperand(0), CUI,
-                                              Op0BO->getName());
-              InsertNewInstBefore(YS, I); // (Y << C)
-              Instruction *X = BinaryOperator::create(Op0BO->getOpcode(), YS,
-                                                      XS->getOperand(0),
-                                                      XS->getName());
-              InsertNewInstBefore(X, I);  // (X + (Y << C))
-              Constant *C2 = ConstantInt::getAllOnesValue(X->getType());
-              C2 = ConstantExpr::getShl(C2, CUI);
-              return BinaryOperator::createAnd(X, C2);
-            }
-          // Fall through.
+          if (isLeftShift && Op0BO->getOperand(1)->hasOneUse() &&
+              match(Op0BO->getOperand(1),
+                    m_Shr(m_Value(V1), m_ConstantInt(CC))) && CC == CUI) {
+            Instruction *YS = new ShiftInst(Instruction::Shl, 
+                                            Op0BO->getOperand(0), CUI,
+                                            Op0BO->getName());
+            InsertNewInstBefore(YS, I); // (Y << C)
+            Instruction *X = BinaryOperator::create(Op0BO->getOpcode(), YS,
+                                                    V1,
+                                               Op0BO->getOperand(1)->getName());
+            InsertNewInstBefore(X, I);  // (X + (Y << C))
+            Constant *C2 = ConstantInt::getAllOnesValue(X->getType());
+            C2 = ConstantExpr::getShl(C2, CUI);
+            return BinaryOperator::createAnd(X, C2);
+          }
+
+          // Turn (Y + ((X >> C) & CC)) << C  ->  ((X & (CC << C)) + (Y << C))
+          if (isLeftShift && Op0BO->getOperand(1)->hasOneUse() &&
+              match(Op0BO->getOperand(1),
+                    m_And(m_Shr(m_Value(V1), m_Value(V2)),
+                          m_ConstantInt(CC))) && V2 == CUI &&
+       cast<BinaryOperator>(Op0BO->getOperand(1))->getOperand(0)->hasOneUse()) {
+            Instruction *YS = new ShiftInst(Instruction::Shl, 
+                                            Op0BO->getOperand(0), CUI,
+                                            Op0BO->getName());
+            InsertNewInstBefore(YS, I); // (Y << C)
+            Instruction *XM =
+              BinaryOperator::createAnd(V1, ConstantExpr::getShl(CC, CUI),
+                                        V1->getName()+".mask");
+            InsertNewInstBefore(XM, I); // X & (CC << C)
+            
+            return BinaryOperator::create(Op0BO->getOpcode(), YS, XM);
+          }
+              
+          // FALL THROUGH.
         case Instruction::Sub:
           // Turn ((X >> C) + Y) << C  ->  (X + (Y << C)) & (~0 << C)
-          if (ShiftInst *XS = dyn_cast<ShiftInst>(Op0BO->getOperand(0)))
-            if (isLeftShift && XS->hasOneUse() && XS->getOperand(1) == CUI &&
-                XS->getOpcode() == Instruction::Shr) {
-              Instruction *YS = new ShiftInst(Instruction::Shl, 
-                                              Op0BO->getOperand(1), CUI,
-                                              Op0BO->getName());
-              InsertNewInstBefore(YS, I); // (Y << C)
-              Instruction *X = BinaryOperator::create(Op0BO->getOpcode(), YS,
-                                                      XS->getOperand(0),
-                                                      XS->getName());
-              InsertNewInstBefore(X, I);  // (X + (Y << C))
-              Constant *C2 = ConstantInt::getAllOnesValue(X->getType());
-              C2 = ConstantExpr::getShl(C2, CUI);
-              return BinaryOperator::createAnd(X, C2);
-            }
+          if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() &&
+              match(Op0BO->getOperand(0),
+                    m_Shr(m_Value(V1), m_ConstantInt(CC))) && CC == CUI) {
+            Instruction *YS = new ShiftInst(Instruction::Shl, 
+                                            Op0BO->getOperand(1), CUI,
+                                            Op0BO->getName());
+            InsertNewInstBefore(YS, I); // (Y << C)
+            Instruction *X = BinaryOperator::create(Op0BO->getOpcode(), YS,
+                                                    V1,
+                                              Op0BO->getOperand(0)->getName());
+            InsertNewInstBefore(X, I);  // (X + (Y << C))
+            Constant *C2 = ConstantInt::getAllOnesValue(X->getType());
+            C2 = ConstantExpr::getShl(C2, CUI);
+            return BinaryOperator::createAnd(X, C2);
+          }
+
+          if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() &&
+              match(Op0BO->getOperand(0),
+                    m_And(m_Shr(m_Value(V1), m_Value(V2)),
+                          m_ConstantInt(CC))) && V2 == CUI &&
+       cast<BinaryOperator>(Op0BO->getOperand(0))->getOperand(0)->hasOneUse()) {
+            Instruction *YS = new ShiftInst(Instruction::Shl, 
+                                            Op0BO->getOperand(1), CUI,
+                                            Op0BO->getName());
+            InsertNewInstBefore(YS, I); // (Y << C)
+            Instruction *XM =
+              BinaryOperator::createAnd(V1, ConstantExpr::getShl(CC, CUI),
+                                        V1->getName()+".mask");
+            InsertNewInstBefore(XM, I); // X & (CC << C)
+            
+            return BinaryOperator::create(Op0BO->getOpcode(), YS, XM);
+          }
+
           break;
         }
 






More information about the llvm-commits mailing list