Fix and/or/xor (cast A), (cast B) --> cast (and/or/xor A, B)
authorReid Spencer <rspencer@reidspencer.com>
Wed, 13 Dec 2006 08:27:15 +0000 (08:27 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Wed, 13 Dec 2006 08:27:15 +0000 (08:27 +0000)
The cast patch introduced the possibility that the wrong cast opcode
could be used and that this transform could trigger on different kinds
of cast operations. This patch rectifies that.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32538 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index 229fb8669d27b945759892fe541b0f8d473d5a83..232e504971c454c17f178fe89629b3a61a84c63d 100644 (file)
@@ -3270,22 +3270,21 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
   }
 
   // fold (and (cast A), (cast B)) -> (cast (and A, B))
-  if (CastInst *Op1C = dyn_cast<CastInst>(Op1)) {
-    if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
-      const Type *SrcTy = Op0C->getOperand(0)->getType();
-      if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegral() &&
-          // Only do this if the casts both really cause code to be generated.
-          ValueRequiresCast(Op0C->getOperand(0), I.getType(), TD) &&
-          ValueRequiresCast(Op1C->getOperand(0), I.getType(), TD)) {
-        Instruction *NewOp = BinaryOperator::createAnd(Op0C->getOperand(0),
-                                                       Op1C->getOperand(0),
-                                                       I.getName());
-        InsertNewInstBefore(NewOp, I);
-        return CastInst::createIntegerCast(NewOp, I.getType(), 
-                                           SrcTy->isSigned());
+  if (CastInst *Op0C = dyn_cast<CastInst>(Op0))
+    if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
+      if (Op0C->getOpcode() == Op1C->getOpcode()) { // same cast kind ?
+        const Type *SrcTy = Op0C->getOperand(0)->getType();
+        if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegral() &&
+            // Only do this if the casts both really cause code to be generated.
+            ValueRequiresCast(Op0C->getOperand(0), I.getType(), TD) &&
+            ValueRequiresCast(Op1C->getOperand(0), I.getType(), TD)) {
+          Instruction *NewOp = BinaryOperator::createAnd(Op0C->getOperand(0),
+                                                         Op1C->getOperand(0),
+                                                         I.getName());
+          InsertNewInstBefore(NewOp, I);
+          return CastInst::create(Op0C->getOpcode(), NewOp, I.getType());
+        }
       }
-    }
-  }
     
   // (X >> Z) & (Y >> Z)  -> (X&Y) >> Z  for all shifts.
   if (ShiftInst *SI1 = dyn_cast<ShiftInst>(Op1)) {
@@ -3675,21 +3674,21 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
   }
     
   // fold (or (cast A), (cast B)) -> (cast (or A, B))
-  if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
-    const Type *SrcTy = Op0C->getOperand(0)->getType();
+  if (CastInst *Op0C = dyn_cast<CastInst>(Op0))
     if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
-      if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegral() &&
-          // Only do this if the casts both really cause code to be generated.
-          ValueRequiresCast(Op0C->getOperand(0), I.getType(), TD) &&
-          ValueRequiresCast(Op1C->getOperand(0), I.getType(), TD)) {
-        Instruction *NewOp = BinaryOperator::createOr(Op0C->getOperand(0),
-                                                      Op1C->getOperand(0),
-                                                      I.getName());
-        InsertNewInstBefore(NewOp, I);
-        return CastInst::createIntegerCast(NewOp, I.getType(),
-                                           SrcTy->isSigned());
+      if (Op0C->getOpcode() == Op1C->getOpcode()) {// same cast kind ?
+        const Type *SrcTy = Op0C->getOperand(0)->getType();
+        if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegral() &&
+            // Only do this if the casts both really cause code to be generated.
+            ValueRequiresCast(Op0C->getOperand(0), I.getType(), TD) &&
+            ValueRequiresCast(Op1C->getOperand(0), I.getType(), TD)) {
+          Instruction *NewOp = BinaryOperator::createOr(Op0C->getOperand(0),
+                                                        Op1C->getOperand(0),
+                                                        I.getName());
+          InsertNewInstBefore(NewOp, I);
+          return CastInst::create(Op0C->getOpcode(), NewOp, I.getType());
+        }
       }
-  }
       
 
   return Changed ? &I : 0;
@@ -3857,21 +3856,21 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
       return R;
 
   // fold (xor (cast A), (cast B)) -> (cast (xor A, B))
-  if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
-    const Type *SrcTy = Op0C->getOperand(0)->getType();
+  if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) 
     if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
-      if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegral() &&
-          // Only do this if the casts both really cause code to be generated.
-          ValueRequiresCast(Op0C->getOperand(0), I.getType(), TD) &&
-          ValueRequiresCast(Op1C->getOperand(0), I.getType(), TD)) {
-        Instruction *NewOp = BinaryOperator::createXor(Op0C->getOperand(0),
-                                                       Op1C->getOperand(0),
-                                                       I.getName());
-        InsertNewInstBefore(NewOp, I);
-        return CastInst::createIntegerCast(NewOp, I.getType(), 
-                                           SrcTy->isSigned());
+      if (Op0C->getOpcode() == Op1C->getOpcode()) { // same cast kind?
+        const Type *SrcTy = Op0C->getOperand(0)->getType();
+        if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegral() &&
+            // Only do this if the casts both really cause code to be generated.
+            ValueRequiresCast(Op0C->getOperand(0), I.getType(), TD) &&
+            ValueRequiresCast(Op1C->getOperand(0), I.getType(), TD)) {
+          Instruction *NewOp = BinaryOperator::createXor(Op0C->getOperand(0),
+                                                         Op1C->getOperand(0),
+                                                         I.getName());
+          InsertNewInstBefore(NewOp, I);
+          return CastInst::create(Op0C->getOpcode(), NewOp, I.getType());
+        }
       }
-  }
 
   // (X >> Z) ^ (Y >> Z)  -> (X^Y) >> Z  for all shifts.
   if (ShiftInst *SI1 = dyn_cast<ShiftInst>(Op1)) {