[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
sabre at nondot.org
Tue Sep 19 21:45:14 PDT 2006
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.513 -> 1.514
---
Log message:
We went through all that trouble to compute whether it was safe to transform
this comparison, but never checked it. Whoops, no wonder we miscompiled
177.mesa!
---
Diffs of the changes: (+46 -6)
InstructionCombining.cpp | 52 +++++++++++++++++++++++++++++++++++++++++------
1 files changed, 46 insertions(+), 6 deletions(-)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.513 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.514
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.513 Tue Sep 19 20:39:40 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Sep 19 23:44:59 2006
@@ -5713,12 +5713,51 @@
return new CastInst(NotCond, SI.getType());
}
- // If one of the constants is zero (we know they can't both be) and we
- // have a setcc instruction with zero, and we have an 'and' with the
- // non-constant value, eliminate this whole mess. This corresponds to
- // cases like this: ((X & 27) ? 27 : 0)
- if (TrueValC->isNullValue() || FalseValC->isNullValue())
- if (SetCondInst *IC = dyn_cast<SetCondInst>(SI.getCondition()))
+ if (SetCondInst *IC = dyn_cast<SetCondInst>(SI.getCondition())) {
+
+ // (x <s 0) ? -1 : 0 -> sra x, 31
+ // (x >u 2147483647) ? -1 : 0 -> sra x, 31
+ if (TrueValC->isAllOnesValue() && FalseValC->isNullValue())
+ if (ConstantInt *CmpCst = dyn_cast<ConstantInt>(IC->getOperand(1))) {
+ bool CanXForm = false;
+ if (CmpCst->getType()->isSigned())
+ CanXForm = CmpCst->isNullValue() &&
+ IC->getOpcode() == Instruction::SetLT;
+ else {
+ unsigned Bits = CmpCst->getType()->getPrimitiveSizeInBits();
+ CanXForm = (CmpCst->getRawValue() == ~0ULL >> (64-Bits+1)) &&
+ IC->getOpcode() == Instruction::SetGT;
+ }
+
+ if (CanXForm) {
+ // The comparison constant and the result are not neccessarily the
+ // same width. In any case, the first step to do is make sure
+ // that X is signed.
+ Value *X = IC->getOperand(0);
+ if (!X->getType()->isSigned())
+ X = InsertCastBefore(X, X->getType()->getSignedVersion(), SI);
+
+ // Now that X is signed, we have to make the all ones value. Do
+ // this by inserting a new SRA.
+ unsigned Bits = X->getType()->getPrimitiveSizeInBits();
+ Constant *ShAmt = ConstantUInt::get(Type::UByteTy, Bits-1);
+ Instruction *SRA = new ShiftInst(Instruction::Shr, X,
+ ShAmt, "ones");
+ InsertNewInstBefore(SRA, SI);
+
+ // Finally, convert to the type of the select RHS. If this is
+ // smaller than the compare value, it will truncate the ones to
+ // fit. If it is larger, it will sext the ones to fit.
+ return new CastInst(SRA, SI.getType());
+ }
+ }
+
+
+ // If one of the constants is zero (we know they can't both be) and we
+ // have a setcc instruction with zero, and we have an 'and' with the
+ // non-constant value, eliminate this whole mess. This corresponds to
+ // cases like this: ((X & 27) ? 27 : 0)
+ if (TrueValC->isNullValue() || FalseValC->isNullValue())
if (IC->isEquality() && isa<ConstantInt>(IC->getOperand(1)) &&
cast<Constant>(IC->getOperand(1))->isNullValue())
if (Instruction *ICA = dyn_cast<Instruction>(IC->getOperand(0)))
@@ -5738,6 +5777,7 @@
Instruction::Xor, V, ICA->getOperand(1)), SI);
return ReplaceInstUsesWith(SI, V);
}
+ }
}
// See if we are selecting two values based on a comparison of the two values.
More information about the llvm-commits
mailing list