[InstCombine] enable optimization of casted vector xor instructions
authorSanjay Patel <spatel@rotateright.com>
Wed, 24 Feb 2016 17:00:34 +0000 (17:00 +0000)
committerSanjay Patel <spatel@rotateright.com>
Wed, 24 Feb 2016 17:00:34 +0000 (17:00 +0000)
This is part of the payoff for the refactoring in:
http://reviews.llvm.org/rL261649
http://reviews.llvm.org/rL261707

In addition to removing a pile of duplicated code, the xor case was
missing the optimization for vector types because it checked
"SrcTy->isIntegerTy()" rather than "SrcTy->isIntOrIntVectorTy()"
like 'and' and 'or' were already doing.

This solves part of:
https://llvm.org/bugs/show_bug.cgi?id=26702

llvm-svn: 261750

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/bitcast.ll

index 8fe598d..d19a022 100644 (file)
@@ -1245,7 +1245,8 @@ static Instruction *matchDeMorgansLaws(BinaryOperator &I,
 
 Instruction *InstCombiner::foldCastedBitwiseLogic(BinaryOperator &I) {
   auto LogicOpc = I.getOpcode();
-  assert((LogicOpc == Instruction::And || LogicOpc == Instruction::Or) &&
+  assert((LogicOpc == Instruction::And || LogicOpc == Instruction::Or ||
+          LogicOpc == Instruction::Xor) &&
          "Unexpected opcode for bitwise logic folding");
 
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
@@ -1277,6 +1278,10 @@ Instruction *InstCombiner::foldCastedBitwiseLogic(BinaryOperator &I) {
     return CastInst::Create(CastOpcode, NewOp, DestTy);
   }
 
+  // For now, only 'and'/'or' have optimizations after this.
+  if (LogicOpc == Instruction::Xor)
+    return nullptr;
+
   // If this is logic(cast(icmp), cast(icmp)), try to fold this even if the
   // cast is otherwise not optimizable.  This happens for vector sexts.
   ICmpInst *ICmp0 = dyn_cast<ICmpInst>(Cast0Src);
@@ -2732,23 +2737,8 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
         }
       }
 
-  // fold (xor (cast A), (cast B)) -> (cast (xor A, B))
-  if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
-    if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
-      if (Op0C->getOpcode() == Op1C->getOpcode()) { // same cast kind?
-        Type *SrcTy = Op0C->getOperand(0)->getType();
-        if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegerTy() &&
-            // Only do this if the casts both really cause code to be generated.
-            ShouldOptimizeCast(Op0C->getOpcode(), Op0C->getOperand(0),
-                               I.getType()) &&
-            ShouldOptimizeCast(Op1C->getOpcode(), Op1C->getOperand(0),
-                               I.getType())) {
-          Value *NewOp = Builder->CreateXor(Op0C->getOperand(0),
-                                            Op1C->getOperand(0), I.getName());
-          return CastInst::Create(Op0C->getOpcode(), NewOp, I.getType());
-        }
-      }
-  }
+  if (Instruction *CastedXor = foldCastedBitwiseLogic(I))
+    return CastedXor;
 
   return Changed ? &I : nullptr;
 }
index 9fcb092..c29f4ed 100644 (file)
@@ -25,9 +25,8 @@ define <2 x i32> @xor_two_vector_bitcasts(<1 x i64> %a, <1 x i64> %b) {
   ret <2 x i32> %t3
 
 ; CHECK-LABEL: @xor_two_vector_bitcasts(
-; CHECK-NEXT:  %t1 = bitcast <1 x i64> %a to <2 x i32>
-; CHECK-NEXT:  %t2 = bitcast <1 x i64> %b to <2 x i32>
-; CHECK-NEXT:  %t3 = xor <2 x i32> %t1, %t2
+; CHECK-NEXT:  %t31 = xor <1 x i64> %a, %b
+; CHECK-NEXT:  %t3 = bitcast <1 x i64> %t31 to <2 x i32>
 ; CHECK-NEXT:  ret <2 x i32> %t3
 }