[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Thu Jan 13 14:52:40 PST 2005
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.300 -> 1.301
---
Log message:
Turn select C, (X+Y), (X-Y) --> (X+(select C, Y, (-Y))). This occurs in
the 'sim' program and probably elsewhere. In sim, it comes up for cases
like this:
#define round(x) ((x)>0.0 ? (x)+0.5 : (x)-0.5)
double G;
void T(double X) { G = round(X); }
(it uses the round macro a lot). This changes the LLVM code from:
%tmp.1 = setgt double %X, 0.000000e+00 ; <bool> [#uses=1]
%tmp.4 = add double %X, 5.000000e-01 ; <double> [#uses=1]
%tmp.6 = sub double %X, 5.000000e-01 ; <double> [#uses=1]
%mem_tmp.0 = select bool %tmp.1, double %tmp.4, double %tmp.6
store double %mem_tmp.0, double* %G
to:
%tmp.1 = setgt double %X, 0.000000e+00 ; <bool> [#uses=1]
%mem_tmp.0.p = select bool %tmp.1, double 5.000000e-01, double -5.000000e-01
%mem_tmp.0 = add double %mem_tmp.0.p, %X
store double %mem_tmp.0, double* %G
ret void
---
Diffs of the changes: (+53 -0)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.300 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.301
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.300 Thu Jan 13 16:25:21 2005
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu Jan 13 16:52:24 2005
@@ -3588,6 +3588,59 @@
}
}
+ // Turn select C, (X+Y), (X-Y) --> (X+(select C, Y, (-Y))). This is legal for
+ // FP as well.
+ if (Instruction *TI = dyn_cast<Instruction>(TrueVal))
+ if (Instruction *FI = dyn_cast<Instruction>(FalseVal))
+ if (TI->hasOneUse() && FI->hasOneUse()) {
+ bool isInverse = false;
+ Instruction *AddOp = 0, *SubOp = 0;
+
+ if (TI->getOpcode() == Instruction::Sub &&
+ FI->getOpcode() == Instruction::Add) {
+ AddOp = FI; SubOp = TI;
+ } else if (FI->getOpcode() == Instruction::Sub &&
+ TI->getOpcode() == Instruction::Add) {
+ AddOp = TI; SubOp = FI;
+ }
+
+ if (AddOp) {
+ Value *OtherAddOp = 0;
+ if (SubOp->getOperand(0) == AddOp->getOperand(0)) {
+ OtherAddOp = AddOp->getOperand(1);
+ } else if (SubOp->getOperand(0) == AddOp->getOperand(1)) {
+ OtherAddOp = AddOp->getOperand(0);
+ }
+
+ if (OtherAddOp) {
+ // So at this point we know we have:
+ // select C, (add X, Y), (sub X, ?)
+ // We can do the transform profitably if either 'Y' = '?' or '?' is
+ // a constant.
+ if (SubOp->getOperand(1) == AddOp ||
+ isa<Constant>(SubOp->getOperand(1))) {
+ Value *NegVal;
+ if (Constant *C = dyn_cast<Constant>(SubOp->getOperand(1))) {
+ NegVal = ConstantExpr::getNeg(C);
+ } else {
+ NegVal = InsertNewInstBefore(
+ BinaryOperator::createNeg(SubOp->getOperand(1)), SI);
+ }
+
+ Value *NewTrueOp = AddOp->getOperand(1);
+ Value *NewFalseOp = NegVal;
+ if (AddOp != TI)
+ std::swap(NewTrueOp, NewFalseOp);
+ Instruction *NewSel =
+ new SelectInst(CondVal, NewTrueOp,NewFalseOp,SI.getName()+".p");
+
+ NewSel = InsertNewInstBefore(NewSel, SI);
+ return BinaryOperator::createAdd(AddOp->getOperand(0), NewSel);
+ }
+ }
+ }
+ }
+
// See if we can fold the select into one of our operands.
if (SI.getType()->isInteger()) {
// See the comment above GetSelectFoldableOperands for a description of the
More information about the llvm-commits
mailing list