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);
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);
}
}
- // 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;
}
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
}