summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2006-12-13 08:27:15 +0000
committerReid Spencer <rspencer@reidspencer.com>2006-12-13 08:27:15 +0000
commit5ae9cebef597db036923de3f653e732384426340 (patch)
tree3634e2c3f662dad960f7e900e428d46c8bb83070
parent8782e53fd5ce0a81f3fa54ee20833629cdac966e (diff)
downloadllvm-5ae9cebef597db036923de3f653e732384426340.tar.gz
llvm-5ae9cebef597db036923de3f653e732384426340.tar.bz2
llvm-5ae9cebef597db036923de3f653e732384426340.tar.xz
Fix and/or/xor (cast A), (cast B) --> cast (and/or/xor A, B)
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
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp81
1 files changed, 40 insertions, 41 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 229fb8669d..232e504971 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -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)) {