[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Apr 9 14:06:04 PDT 2004
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.183 -> 1.184
---
Log message:
Fold binary operators with a constant operand into select instructions
that have a constant operand. This implements
add.ll:test19, shift.ll:test15*, and others that are not tested
---
Diffs of the changes: (+94 -15)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.183 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.184
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.183 Fri Apr 9 13:19:44 2004
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Apr 9 14:05:30 2004
@@ -489,7 +489,50 @@
}
};
+static Value *FoldOperationIntoSelectOperand(Instruction &BI, Value *SO,
+ InstCombiner *IC) {
+ // Figure out if the constant is the left or the right argument.
+ bool ConstIsRHS = isa<Constant>(BI.getOperand(1));
+ Constant *ConstOperand = cast<Constant>(BI.getOperand(ConstIsRHS));
+
+ if (Constant *SOC = dyn_cast<Constant>(SO)) {
+ if (ConstIsRHS)
+ return ConstantExpr::get(BI.getOpcode(), SOC, ConstOperand);
+ return ConstantExpr::get(BI.getOpcode(), ConstOperand, SOC);
+ }
+
+ Value *Op0 = SO, *Op1 = ConstOperand;
+ if (!ConstIsRHS)
+ std::swap(Op0, Op1);
+ Instruction *New;
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(&BI))
+ New = BinaryOperator::create(BO->getOpcode(), Op0, Op1);
+ else if (ShiftInst *SI = dyn_cast<ShiftInst>(&BI))
+ New = new ShiftInst(SI->getOpcode(), Op0, Op1);
+ else
+ assert(0 && "Unknown binary instruction type!");
+ return IC->InsertNewInstBefore(New, BI);
+}
+
+// FoldBinOpIntoSelect - Given an instruction with a select as one operand and a
+// constant as the other operand, try to fold the binary operator into the
+// select arguments.
+static Instruction *FoldBinOpIntoSelect(Instruction &BI, SelectInst *SI,
+ InstCombiner *IC) {
+ // Don't modify shared select instructions
+ if (!SI->hasOneUse()) return 0;
+ Value *TV = SI->getOperand(1);
+ Value *FV = SI->getOperand(2);
+
+ if (isa<Constant>(TV) || isa<Constant>(FV)) {
+ Value *SelectTrueVal = FoldOperationIntoSelectOperand(BI, TV, IC);
+ Value *SelectFalseVal = FoldOperationIntoSelectOperand(BI, FV, IC);
+ return new SelectInst(SI->getCondition(), SelectTrueVal,
+ SelectFalseVal);
+ }
+ return 0;
+}
Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
bool Changed = SimplifyCommutative(I);
@@ -547,6 +590,11 @@
CRHS, ConstantInt::get(I.getType(), 1)),
ILHS->getOperand(0));
break;
+ case Instruction::Select:
+ // Try to fold constant add into select arguments.
+ if (Instruction *R = FoldBinOpIntoSelect(I,cast<SelectInst>(ILHS),this))
+ return R;
+
default: break;
}
}
@@ -632,6 +680,11 @@
}
}
}
+
+ // Try to fold constant sub into select arguments.
+ if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
+ if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+ return R;
}
if (BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1))
@@ -740,6 +793,11 @@
if (Op1F->getValue() == 1.0)
return ReplaceInstUsesWith(I, Op0); // Eliminate 'mul double %X, 1.0'
}
+
+ // Try to fold constant mul into select arguments.
+ if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
+ if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+ return R;
}
if (Value *Op0v = dyn_castNegVal(Op0)) // -X * -Y = X*Y
@@ -1093,6 +1151,11 @@
if (Instruction *Res = OptAndOp(Op0I, Op0CI, RHS, I))
return Res;
}
+
+ // Try to fold constant and into select arguments.
+ if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
+ if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+ return R;
}
Value *Op0NotVal = dyn_castNotVal(Op0);
@@ -1158,6 +1221,11 @@
NotConstant(RHS)));
}
}
+
+ // Try to fold constant and into select arguments.
+ if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
+ if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+ return R;
}
// (A & C1)|(A & C2) == A & (C1|C2)
@@ -1268,6 +1336,11 @@
default: break;
}
}
+
+ // Try to fold constant and into select arguments.
+ if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
+ if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+ return R;
}
if (Value *X = dyn_castNotVal(Op0)) // ~A ^ A == -1
@@ -1668,6 +1741,12 @@
if (CSI->isAllOnesValue())
return ReplaceInstUsesWith(I, CSI);
+ // Try to fold constant and into select arguments.
+ if (isa<Constant>(Op0))
+ if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
+ if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+ return R;
+
if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op1)) {
// shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr
// of a signed value.
@@ -1689,6 +1768,10 @@
return BinaryOperator::create(Instruction::Mul, BO->getOperand(0),
ConstantExpr::get(Instruction::Shl, BOOp, CUI));
+ // Try to fold constant and into select arguments.
+ if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
+ if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+ return R;
// If the operand is an bitwise operator with a constant RHS, and the
// shift is the only use, we can pull it out of the shift.
@@ -2052,22 +2135,18 @@
}
}
- // Selecting between two constants?
- if (Constant *TrueValC = dyn_cast<Constant>(TrueVal))
- if (Constant *FalseValC = dyn_cast<Constant>(FalseVal)) {
- if (SI.getType()->isInteger()) {
- // select C, 1, 0 -> cast C to int
- if (FalseValC->isNullValue() && isa<ConstantInt>(TrueValC) &&
- cast<ConstantInt>(TrueValC)->getRawValue() == 1) {
- return new CastInst(CondVal, SI.getType());
- } else if (TrueValC->isNullValue() && isa<ConstantInt>(FalseValC) &&
- cast<ConstantInt>(FalseValC)->getRawValue() == 1) {
- // select C, 0, 1 -> cast !C to int
- Value *NotCond =
- InsertNewInstBefore(BinaryOperator::createNot(CondVal,
+ // Selecting between two integer constants?
+ if (ConstantInt *TrueValC = dyn_cast<ConstantInt>(TrueVal))
+ if (ConstantInt *FalseValC = dyn_cast<ConstantInt>(FalseVal)) {
+ // select C, 1, 0 -> cast C to int
+ if (FalseValC->isNullValue() && TrueValC->getRawValue() == 1) {
+ return new CastInst(CondVal, SI.getType());
+ } else if (TrueValC->isNullValue() && FalseValC->getRawValue() == 1) {
+ // select C, 0, 1 -> cast !C to int
+ Value *NotCond =
+ InsertNewInstBefore(BinaryOperator::createNot(CondVal,
"not."+CondVal->getName()), SI);
- return new CastInst(NotCond, SI.getType());
- }
+ return new CastInst(NotCond, SI.getType());
}
}
More information about the llvm-commits
mailing list