summaryrefslogtreecommitdiffstats
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
commit799b5bfc71e9f0de3d0c3539a1554813e4c2658a (patch)
tree931ae37ff30acdb4220a508a80b7deb919e5a444
parent20f7a2a09b4686ffa8a4da76e875dda4c4eab0f8 (diff)
downloadbcm5719-llvm-799b5bfc71e9f0de3d0c3539a1554813e4c2658a.tar.gz
bcm5719-llvm-799b5bfc71e9f0de3d0c3539a1554813e4c2658a.zip
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. llvm-svn: 32538
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp81
1 files changed, 40 insertions, 41 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index 229fb8669d2..232e504971c 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/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)) {
OpenPOWER on IntegriCloud