From dbbaca0e1b5d9a6e36ffdf523c946f02fd6c2357 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 24 Feb 2016 17:00:34 +0000 Subject: [PATCH] [InstCombine] enable optimization of casted vector xor instructions 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 --- .../Transforms/InstCombine/InstCombineAndOrXor.cpp | 26 +++++++--------------- llvm/test/Transforms/InstCombine/bitcast.ll | 5 ++--- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 8fe598d..d19a022 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -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(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(Op0)) { - if (CastInst *Op1C = dyn_cast(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; } diff --git a/llvm/test/Transforms/InstCombine/bitcast.ll b/llvm/test/Transforms/InstCombine/bitcast.ll index 9fcb092..c29f4ed 100644 --- a/llvm/test/Transforms/InstCombine/bitcast.ll +++ b/llvm/test/Transforms/InstCombine/bitcast.ll @@ -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 } -- 2.7.4