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

Chris Lattner lattner at cs.uiuc.edu
Fri Jan 6 17:32:40 PST 2006



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.410 -> 1.411
---
Log message:

fix some 176.gcc miscompilation from my previous patch.


---
Diffs of the changes:  (+33 -7)

 InstructionCombining.cpp |   40 +++++++++++++++++++++++++++++++++-------
 1 files changed, 33 insertions(+), 7 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.410 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.411
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.410	Fri Jan  6 11:59:59 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Fri Jan  6 19:32:28 2006
@@ -3669,7 +3669,7 @@
     // is a noop cast between the two.
     bool isShiftOfLeftShift = ShiftOp->getOpcode() == Instruction::Shl;
     bool isShiftOfSignedShift = ShiftOp->getType()->isSigned();
-    bool isShiftOfUnsignedShift = !isSignedShift;
+    bool isShiftOfUnsignedShift = !isShiftOfSignedShift;
     
     ConstantUInt *ShiftAmt1C = cast<ConstantUInt>(ShiftOp->getOperand(1));
 
@@ -3704,7 +3704,7 @@
       if (isLeftShift)
         C = ConstantExpr::getShl(C, ShiftAmt1C);
       else
-        C = ConstantExpr::getShr(C, ShiftAmt1C); // must be an unsigned shr.
+        C = ConstantExpr::getUShr(C, ShiftAmt1C);
       
       Value *Op = ShiftOp->getOperand(0);
       if (isShiftOfSignedShift != isSignedShift)
@@ -3715,17 +3715,43 @@
       InsertNewInstBefore(Mask, I);
       
       // Figure out what flavor of shift we should use...
-      if (ShiftAmt1 == ShiftAmt2)
+      if (ShiftAmt1 == ShiftAmt2) {
         return ReplaceInstUsesWith(I, Mask);  // (A << c) >> c  === A & c2
-      else if (ShiftAmt1 < ShiftAmt2) {
+      } else if (ShiftAmt1 < ShiftAmt2) {
         return new ShiftInst(I.getOpcode(), Mask,
                          ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1));
-      } else {
-        return new ShiftInst(ShiftOp->getOpcode(), Mask,
+      } else if (isShiftOfUnsignedShift || isShiftOfLeftShift) {
+        if (isShiftOfUnsignedShift && !isShiftOfLeftShift && isSignedShift) {
+          // Make sure to emit an unsigned shift right, not a signed one.
+          Mask = InsertNewInstBefore(new CastInst(Mask, 
+                                        Mask->getType()->getUnsignedVersion(),
+                                                  Op->getName()), I);
+          Mask = new ShiftInst(Instruction::Shr, Mask,
                          ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2));
+          InsertNewInstBefore(Mask, I);
+          return new CastInst(Mask, I.getType());
+        } else {
+          return new ShiftInst(ShiftOp->getOpcode(), Mask,
+                    ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2));
+        }
+      } else {
+        // (X >>s C1) << C2  where C1 > C2  === (X >>s (C1-C2)) & mask
+        Op = InsertNewInstBefore(new CastInst(Mask,
+                                              I.getType()->getSignedVersion(),
+                                              Mask->getName()), I);
+        Instruction *Shift =
+          new ShiftInst(ShiftOp->getOpcode(), Op,
+                        ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2));
+        InsertNewInstBefore(Shift, I);
+        
+        C = ConstantIntegral::getAllOnesValue(Shift->getType());
+        C = ConstantExpr::getShl(C, Op1);
+        Mask = BinaryOperator::createAnd(Shift, C, Op->getName()+".mask");
+        InsertNewInstBefore(Mask, I);
+        return new CastInst(Mask, I.getType());
       }
     } else {
-      // We can handle signed (X << C1) >> C2 if it's a sign extend.  In
+      // We can handle signed (X << C1) >>s C2 if it's a sign extend.  In
       // this case, C1 == C2 and C1 is 8, 16, or 32.
       if (ShiftAmt1 == ShiftAmt2) {
         const Type *SExtType = 0;






More information about the llvm-commits mailing list