[llvm-commits] SETCC Patches: #3
Chris Lattner
clattner at apple.com
Mon Dec 11 22:51:38 PST 2006
On Dec 10, 2006, at 3:43 PM, Reid Spencer wrote:
> All,
>
> Here's the SETCC patch to convert SetCondInst (SetCC) instructions
> into
> ICmpInst. Here's somethings you should know about this patch:
This is all the rest, except for instcombine.
Index: tools/llvm-upgrade/UpgradeParser.y
===================================================================
RCS file: /var/cvs/llvm/llvm/tools/llvm-upgrade/UpgradeParser.y,v
retrieving revision 1.24
diff -t -d -u -p -5 -r1.24 UpgradeParser.y
--- tools/llvm-upgrade/UpgradeParser.y 9 Dec 2006 19:40:41 -0000 1.24
+++ tools/llvm-upgrade/UpgradeParser.y 10 Dec 2006 23:27:00 -0000
@@ -21,11 +21,11 @@
#include <cassert>
#define YYERROR_VERBOSE 1
#define YYINCLUDED_STDLIB_H
#define YYDEBUG 1
-#define UPGRADE_SETCOND_OPS 0
+#define UPGRADE_SETCOND_OPS 1
#define GENERATE_FCMP_INSTS 0
int yylex(); // declaration" of xxx warnings.
int yyparse();
extern int yydebug;
This #ifdef should go away now, since it's always on.
Index: lib/ExecutionEngine/Interpreter/Execution.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/ExecutionEngine/Interpreter/
Execution.cpp,v
retrieving revision 1.152
diff -t -d -u -p -5 -r1.152 Execution.cpp
--- lib/ExecutionEngine/Interpreter/Execution.cpp 7 Dec 2006 01:30:31
-0000 1.152
+++ lib/ExecutionEngine/Interpreter/Execution.cpp 10 Dec 2006
23:26:54 -0000
...
+static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue
Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ switch (Ty->getTypeID()) {
+ IMPLEMENT_CMP(<, UByte);
+ IMPLEMENT_CMP(<, UShort);
+ IMPLEMENT_CMP(<, UInt);
+ IMPLEMENT_CMP(<, ULong);
+ IMPLEMENT_POINTERCMP(<);
+ default:
+ cerr << "Unhandled type for ICMP_ULT predicate: " << *Ty << "\n";
+ abort();
+ }
+ return Dest;
+}
The interpreter is broken: all unsigned comparisons with signed
operands will hit the unhandled type case.
Index: lib/Target/CBackend/Writer.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/CBackend/Writer.cpp,v
retrieving revision 1.294
diff -t -d -u -p -5 -r1.294 Writer.cpp
--- lib/Target/CBackend/Writer.cpp 7 Dec 2006 23:41:45 -0000 1.294
+++ lib/Target/CBackend/Writer.cpp 10 Dec 2006 23:26:54 -0000
@@ -712,10 +717,44 @@ void CWriter::printConstant(Constant *CP
case Instruction::SetGT: Out << " > "; break;
case Instruction::SetGE: Out << " >= "; break;
case Instruction::Shl: Out << " << "; break;
case Instruction::LShr:
case Instruction::AShr: Out << " >> "; break;
+ case Instruction::ICmp:
+ switch (CE->getPredicate()) {
+ case ICmpInst::ICMP_EQ: Out << " == "; break;
+ case ICmpInst::ICMP_NE: Out << " != "; break;
+ case ICmpInst::ICMP_SLT:
+ case ICmpInst::ICMP_ULT: Out << " < "; break;
+ case ICmpInst::ICMP_SLE:
+ case ICmpInst::ICMP_ULE: Out << " <= "; break;
...
This apparently doesn't cast the operands of icmp constant exprs to
the right sign.
@@ -1122,10 +1161,65 @@ void CWriter::writeOperandWithCast(Value
+
+// generateCompilerSpecificCode - This is where we add conditional
compilation
+// directives to cater to specific compilers as need be.
+//
+
// generateCompilerSpecificCode - This is where we add conditional
compilation
// directives to cater to specific compilers as need be.
//
... There ya go again, trying to inflate your LOC count.
@@ -1982,10 +2076,49 @@ void CWriter::visitBinaryOperator(Instru
if (needsCast) {
Out << "))";
}
}
+void CWriter::visitICmpInst(Instruction &I) {
+ // icmp instruction.
+ assert(isa<ICmpInst>(I));
+
Drop the isa and later casts, change the argument to visitICmpInst to
ICmpInst.
Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/SelectionDAG/
SelectionDAGISel.cpp,v
retrieving revision 1.326
diff -t -d -u -p -5 -r1.326 SelectionDAGISel.cpp
--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp 9 Dec 2006 02:42:38
-0000 1.326
+++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp 10 Dec 2006
23:26:53 -0000
+ BOp = cast<Instruction>(Cond);
+ ISD::CondCode Condition;
+ if (SetCondInst *SCI = dyn_cast<SetCondInst>(Cond)) {
+ ISD::CondCode SignCond, UnsCond, FPCond;
+ switch (BOp->getOpcode()) {
+ default: assert(0 && "Unknown setcc opcode!");
+ case Instruction::SetEQ:
+ SignCond = ISD::SETEQ;
+ UnsCond = ISD::SETEQ;
+ FPCond = ISD::SETOEQ;
+ break;
+ case Instruction::SetNE:
+ SignCond = ISD::SETNE;
+ UnsCond = ISD::SETNE;
+ FPCond = ISD::SETUNE;
+ break;
+ case Instruction::SetLE:
+ SignCond = ISD::SETLE;
+ UnsCond = ISD::SETULE;
+ FPCond = ISD::SETOLE;
+ break;
+ case Instruction::SetGE:
+ SignCond = ISD::SETGE;
+ UnsCond = ISD::SETUGE;
+ FPCond = ISD::SETOGE;
+ break;
+ case Instruction::SetLT:
+ SignCond = ISD::SETLT;
+ UnsCond = ISD::SETULT;
+ FPCond = ISD::SETOLT;
+ break;
+ case Instruction::SetGT:
+ SignCond = ISD::SETGT;
+ UnsCond = ISD::SETUGT;
+ FPCond = ISD::SETOGT;
+ break;
+ }
+ const Type *OpType = SCI->getOperand(0)->getType();
+ if (const PackedType *PTy = dyn_cast<PackedType>(OpType))
+ OpType = PTy->getElementType();
+
+ if (!FiniteOnlyFPMath() && OpType->isFloatingPoint())
+ Condition = FPCond;
+ else if (OpType->isUnsigned())
+ Condition = UnsCond;
+ else
+ Condition = SignCond;
You can drop UnsCond here, as SetCondInst doesn't apply to integers
anymore.
+ } else if (FCmpInst *FC = dyn_cast<FCmpInst>(Cond)) {
+ switch (FC->getPredicate()) {
+ default: assert(0 && "Unknown fcmp predicate opcode!");
+ case FCmpInst::FCMP_FALSE: Condition = ISD::SETFALSE; break;
+ case FCmpInst::FCMP_OEQ: Condition = ISD::SETOEQ; break;
+ case FCmpInst::FCMP_OGT: Condition = ISD::SETOGT; break;
+ case FCmpInst::FCMP_OGE: Condition = ISD::SETOGE; break;
+ case FCmpInst::FCMP_OLT: Condition = ISD::SETOLT; break;
+ case FCmpInst::FCMP_OLE: Condition = ISD::SETOLE; break;
+ case FCmpInst::FCMP_ONE: Condition = ISD::SETONE; break;
+ case FCmpInst::FCMP_ORD: Condition = ISD::SETO; break;
+ case FCmpInst::FCMP_UNO: Condition = ISD::SETUO; break;
+ case FCmpInst::FCMP_UEQ: Condition = ISD::SETUEQ; break;
+ case FCmpInst::FCMP_UGT: Condition = ISD::SETUGT; break;
+ case FCmpInst::FCMP_UGE: Condition = ISD::SETUGE; break;
+ case FCmpInst::FCMP_ULT: Condition = ISD::SETULT; break;
+ case FCmpInst::FCMP_ULE: Condition = ISD::SETULE; break;
+ case FCmpInst::FCMP_UNE: Condition = ISD::SETUNE; break;
+ case FCmpInst::FCMP_TRUE: Condition = ISD::SETTRUE; break;
+ }
This (when it becomes active) isn't sufficient. When
FiniteOnlyFPMath is enabled, all the 'o's and 'u's should get dropped.
void SelectionDAGLowering::visitFCmp(User &I) {
+ FCmpInst::Predicate predicate = FCmpInst::BAD_FCMP_PREDICATE;
+ if (FCmpInst *FC = dyn_cast<FCmpInst>(&I))
likewise.
diff -t -d -u -p -5 -r1.107 SimplifyCFG.cpp
--- lib/Transforms/Utils/SimplifyCFG.cpp 27 Nov 2006 01:05:10 -0000
1.107
+++ lib/Transforms/Utils/SimplifyCFG.cpp 10 Dec 2006 23:26:51 -0000
@@ -388,23 +390,43 @@ static bool DominatesMergePoint(Value *V
}
return true;
}
-// GatherConstantSetEQs - Given a potentially 'or'd together
collection of seteq
-// instructions that compare a value against a constant, return the
value being
-// compared, and stick the constant into the Values vector.
+// GatherConstantSetEQs - Given a potentially 'or'd together
collection of
+// icmp_eq instructions that compare a value against a constant,
return the
+// value being compared, and stick the constant into the Values vector.
static Value *GatherConstantSetEQs(Value *V,
std::vector<ConstantInt*> &Values){
if (Instruction *Inst = dyn_cast<Instruction>(V))
if (Inst->getOpcode() == Instruction::SetEQ) {
if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand
(1))) {
Values.push_back(C);
return Inst->getOperand(0);
} else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst-
>getOperand(0))) {
Values.push_back(C);
return Inst->getOperand(1);
}
This code is dead because integer seteq can't exist anymore (it's icmp).
+ } else if (Inst->getOpcode() == Instruction::ICmp &&
+ cast<ICmpInst>(Inst)->getPredicate() == ICmpInst::ICMP_EQ) {
+ if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand
(1))) {
+ Values.push_back(C);
+ return Inst->getOperand(0);
+ } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst-
>getOperand(0))) {
+ Values.push_back(C);
+ return Inst->getOperand(1);
+ }
+ } else if (FCmpInst *FCI = dyn_cast<FCmpInst>(Inst)) {
+ FCmpInst::Predicate pred = FCI->getPredicate();
+ if (pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE) {
+ if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand
(1))) {
+ Values.push_back(C);
+ return Inst->getOperand(0);
+ } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst-
>getOperand(0))){
+ Values.push_back(C);
+ return Inst->getOperand(1);
+ }
+ }
FCmpInst's can't have constantint operands, this code is dead.
@@ -423,10 +445,30 @@ static Value *GatherConstantSetNEs(Value
return Inst->getOperand(0);
} else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst-
>getOperand(0))) {
Values.push_back(C);
return Inst->getOperand(1);
}
+ } else if (Inst->getOpcode() == Instruction::ICmp &&
+ cast<ICmpInst>(Inst)->getPredicate() ==
ICmpInst::ICMP_NE) {
+ if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand
(1))) {
+ Values.push_back(C);
+ return Inst->getOperand(0);
+ } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst-
>getOperand(0))) {
+ Values.push_back(C);
+ return Inst->getOperand(1);
+ }
+ } else if (FCmpInst *FCI = dyn_cast<FCmpInst>(Inst)) {
+ FCmpInst::Predicate pred = FCI->getPredicate();
+ if (pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE) {
+ if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand
(1))) {
+ Values.push_back(C);
+ return Inst->getOperand(0);
+ } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst-
>getOperand(0))){
+ Values.push_back(C);
+ return Inst->getOperand(1);
+ }
+ }
Likewise. Since you're handling integers, you can nuke the old
SetCondInst code here.
@@ -845,12 +887,11 @@ static bool HoistThenElseCodeToIf(Branch
// identical order.
BasicBlock *BB1 = BI->getSuccessor(0); // The true destination.
BasicBlock *BB2 = BI->getSuccessor(1); // The false destination
Instruction *I1 = BB1->begin(), *I2 = BB2->begin();
- if (I1->getOpcode() != I2->getOpcode() || !I1->isIdenticalTo(I2) ||
- isa<PHINode>(I1) || isa<InvokeInst>(I1))
+ if (!I1->isIdenticalTo(I2) || isa<PHINode>(I1) || isa<InvokeInst>
(I1))
return false;
// If we get here, we can hoist at least one instruction.
BasicBlock *BIParent = BI->getParent();
Why did you drop the opcode check? It is a fast reject path.
@@ -868,11 +909,11 @@ static bool HoistThenElseCodeToIf(Branch
I2->replaceAllUsesWith(I1);
BB2->getInstList().erase(I2);
I1 = BB1->begin();
I2 = BB2->begin();
- } while (I1->getOpcode() == I2->getOpcode() && I1->isIdenticalTo
(I2));
+ } while (I1->isIdenticalTo(I2));
likewise.
Index: lib/Transforms/Utils/CloneFunction.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Transforms/Utils/CloneFunction.cpp,v
retrieving revision 1.33
diff -t -d -u -p -5 -r1.33 CloneFunction.cpp
--- lib/Transforms/Utils/CloneFunction.cpp 5 Nov 2006 19:31:28 -0000
1.33
+++ lib/Transforms/Utils/CloneFunction.cpp 10 Dec 2006 23:26:50 -0000
@@ -276,16 +276,19 @@ void PruningFunctionCloner::CloneBlock(c
/// ConstantFoldMappedInstruction - Constant fold the specified
instruction,
/// mapping its operands through ValueMap if they are available.
Constant *PruningFunctionCloner::
ConstantFoldMappedInstruction(const Instruction *I) {
- if (isa<BinaryOperator>(I) || isa<ShiftInst>(I)) {
+ if (isa<BinaryOperator>(I) || isa<ShiftInst>(I) || isa<CmpInst>(I)) {
if (Constant *Op0 = dyn_cast_or_null<Constant>(MapValue(I-
>getOperand(0),
ValueMap)))
if (Constant *Op1 = dyn_cast_or_null<Constant>(MapValue(I-
>getOperand(1),
ValueMap)))
- return ConstantExpr::get(I->getOpcode(), Op0, Op1);
+ return isa<CmpInst>(I) ?
+ ConstantExpr::getCompare(I->getOpcode(),
+ cast<CmpInst>(I)->getPredicate(), Op0, Op1) :
+ ConstantExpr::get(I->getOpcode(), Op0, Op1);
return 0;
}
It seems more natural to split CmpInst out from binop/shift handling
into a separate if, to eliminate the ternary operator.
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Transforms/Scalar/Reassociate.cpp,v
retrieving revision 1.68
diff -t -d -u -p -5 -r1.68 Reassociate.cpp
--- lib/Transforms/Scalar/Reassociate.cpp 7 Dec 2006 20:04:42 -0000 1.68
+++ lib/Transforms/Scalar/Reassociate.cpp 10 Dec 2006 23:26:49 -0000
@@ -754,12 +755,12 @@ void Reassociate::ReassociateBB(BasicBlo
MadeChange = true;
BI = NI;
}
// Reject cases where it is pointless to do this.
- if (!isa<BinaryOperator>(BI) || BI->getType()->isFloatingPoint() ||
- isa<PackedType>(BI->getType()))
+ if (!isa<BinaryOperator>(BI) || BI->getType()->isFloatingPoint() ||
+ isa<PackedType>(BI->getType()))
continue; // Floating point ops are not associative.
This change looks like an incorrect indentation change.
Index: lib/Transforms/Scalar/LoopUnswitch.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp,v
retrieving revision 1.51
diff -t -d -u -p -5 -r1.51 LoopUnswitch.cpp
--- lib/Transforms/Scalar/LoopUnswitch.cpp 6 Dec 2006 17:46:33 -0000
1.51
+++ lib/Transforms/Scalar/LoopUnswitch.cpp 10 Dec 2006 23:26:48 -0000
@@ -486,11 +486,14 @@ static void EmitPreheaderBranchOnConditi
Instruction *InsertPt) {
// Insert a conditional branch on LIC to the two preheaders. The
original
// code is the true version and the new code is the false version.
Value *BranchVal = LIC;
if (!isa<ConstantBool>(Val)) {
- BranchVal = BinaryOperator::createSetEQ(LIC, Val, "tmp", InsertPt);
+ if (Val->getType()->isFloatingPoint())
+ BranchVal = BinaryOperator::createSetEQ(LIC, Val, "tmp",
InsertPt);
+ else
+ BranchVal = new ICmpInst(ICmpInst::ICMP_EQ, LIC, Val, "tmp",
InsertPt);
} else if (Val != ConstantBool::getTrue()) {
// We want to enter the new loop when the condition is true.
std::swap(TrueDest, FalseDest);
}
It's not obvious from immediate context, but this is always an
integer comparison.
diff -t -d -u -p -5 -r1.98 LoopStrengthReduce.cpp
--- lib/Transforms/Scalar/LoopStrengthReduce.cpp 7 Dec 2006 01:30:31
-0000 1.98
+++ lib/Transforms/Scalar/LoopStrengthReduce.cpp 10 Dec 2006 23:26:48
-0000
@@ -1187,14 +1187,20 @@ void LoopStrengthReduce::OptimizeIndvars
PHINode *SomePHI = cast<PHINode>(L->getHeader()->begin());
BasicBlock *Preheader = L->getLoopPreheader();
BasicBlock *LatchBlock =
SomePHI->getIncomingBlock(SomePHI->getIncomingBlock(0) ==
Preheader);
BranchInst *TermBr = dyn_cast<BranchInst>(LatchBlock-
>getTerminator());
+ bool isICmp;
if (!TermBr || TermBr->isUnconditional() ||
- !isa<SetCondInst>(TermBr->getCondition()))
+ (!(isICmp = isa<ICmpInst>(TermBr->getCondition()) &&
+ !isa<SetCondInst>(TermBr->getCondition()))))
return;
- SetCondInst *Cond = cast<SetCondInst>(TermBr->getCondition());
+ Instruction *Cond;
+ if (isICmp)
+ Cond = cast<ICmpInst>(TermBr->getCondition());
+ else
+ Cond = cast<SetCondInst>(TermBr->getCondition());
This code only cares about integer comparisons. Please change Cond
to be ICmpInst*.
@@ -1223,11 +1229,14 @@ void LoopStrengthReduce::OptimizeIndvars
if (&*++BasicBlock::iterator(Cond) != (Instruction*)TermBr) {
if (Cond->hasOneUse()) { // Condition has a single use, just
move it.
Cond->moveBefore(TermBr);
} else {
// Otherwise, clone the terminating condition and insert into
the loopend.
- Cond = cast<SetCondInst>(Cond->clone());
+ if (isICmp)
+ Cond = cast<ICmpInst>(Cond->clone());
+ else
+ Cond = cast<SetCondInst>(Cond->clone());
Cond->setName(L->getHeader()->getName() + ".termcond");
LatchBlock->getInstList().insert(TermBr, Cond);
// Clone the IVUse, as the old use still exists!
IVUsesByStride[*CondStride].addUser(CondUse->Offset, Cond,
Likewise.
@@ -1344,19 +1353,26 @@ void LoopStrengthReduce::runOnLoop(Loop
// If all four cases above are true, then we can remove both
the add and
// the cann indvar.
// FIXME: this needs to eliminate an induction variable even
if it's being
// compared against some value to decide loop termination.
if (PN->hasOneUse()) {
- BinaryOperator *BO = dyn_cast<BinaryOperator>(*(PN->use_begin
()));
- if (BO && BO->hasOneUse()) {
- if (PN == *(BO->use_begin())) {
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(*(PN-
>use_begin()))) {
+ if (BO->hasOneUse() && PN == *(BO->use_begin())) {
DeadInsts.insert(BO);
// Break the cycle, then delete the PHI.
PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
SE->deleteInstructionFromRecords(PN);
PN->eraseFromParent();
}
+ } else if (CmpInst *CI = dyn_cast<CmpInst>(*(PN->use_begin
()))) {
+ if (CI->hasOneUse() && PN == *(CI->use_begin())) {
+ DeadInsts.insert(CI);
+ // Break the cycle, then delete the PHI.
+ PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
+ SE->deleteInstructionFromRecords(PN);
+ PN->eraseFromParent();
+ }
Instead of cloning the code, how about something like:
// FIXME: this needs to eliminate an induction variable even
if it's being
// compared against some value to decide loop termination.
if (PN->hasOneUse()) {
Instruction *BO = *PN->use_begin();
if (isa<BinaryOperator>(BO) || isa<CmpInst>(BO)) {
+ if (BO->hasOneUse() && PN == *(BO->use_begin())) {
DeadInsts.insert(BO);
// Break the cycle, then delete the PHI.
PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
SE->deleteInstructionFromRecords(PN);
PN->eraseFromParent();
}
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp,v
retrieving revision 1.74
diff -t -d -u -p -5 -r1.74 SimplifyLibCalls.cpp
--- lib/Transforms/IPO/SimplifyLibCalls.cpp 6 Dec 2006 17:46:32 -0000
1.74
+++ lib/Transforms/IPO/SimplifyLibCalls.cpp 10 Dec 2006 23:26:42 -0000
@@ -941,10 +941,16 @@ static bool IsOnlyUsedInEqualsZeroCompar
if (User->getOpcode() == Instruction::SetNE ||
User->getOpcode() == Instruction::SetEQ) {
if (isa<Constant>(User->getOperand(1)) &&
cast<Constant>(User->getOperand(1))->isNullValue())
continue;
+ } else if (ICmpInst *IC = dyn_cast<ICmpInst>(User)) {
+ if ((IC->getPredicate() == ICmpInst::ICMP_NE ||
+ IC->getPredicate() == ICmpInst::ICMP_EQ) &&
+ isa<Constant>(IC->getOperand(1)) &&
+ cast<Constant>(IC->getOperand(1))->isNullValue())
+ continue;
} else if (CastInst *CI = dyn_cast<CastInst>(User))
if (CI->getType() == Type::BoolTy)
continue;
// Unknown instruction.
return false;
The FP case is dead here.
@@ -1769,13 +1775,13 @@ public:
// isascii(c) -> (unsigned)c < 128
Value *V = CI->getOperand(1);
if (V->getType()->isSigned())
V = CastInst::createInferredCast(V, V->getType()-
>getUnsignedVersion(),
V->getName(), CI);
- Value *Cmp = BinaryOperator::createSetLT(V, ConstantInt::get(V-
>getType(),
- 128),
- V->getName()
+".isascii", CI);
+ Value *Cmp = new ICmpInst(ICmpInst::ICMP_ULT, V,
+ ConstantInt::get(V->getType(), 128),
+ V->getName()+".isascii", CI);
if (Cmp->getType() != CI->getType())
Cmp = CastInst::createInferredCast(
Cmp, CI->getType(), Cmp->getName(), CI);
CI->replaceAllUsesWith(Cmp);
CI->eraseFromParent();
You can drop the createInferredCast (which should have been a
bitcast) now that compares are signless?
diff -t -d -u -p -5 -r1.78 GlobalOpt.cpp
--- lib/Transforms/IPO/GlobalOpt.cpp 7 Dec 2006 01:30:31 -0000 1.78
+++ lib/Transforms/IPO/GlobalOpt.cpp 10 Dec 2006 23:26:41 -0000
@@ -722,15 +722,53 @@ static GlobalVariable *OptimizeGlobalAdd
std::vector<StoreInst*> Stores;
while (!GV->use_empty())
if (LoadInst *LI = dyn_cast<LoadInst>(GV->use_back())) {
while (!LI->use_empty()) {
Use &LoadUse = LI->use_begin().getUse();
- if (!isa<SetCondInst>(LoadUse.getUser()))
- LoadUse = RepValue;
- else {
+ if (CmpInst *CI = dyn_cast<CmpInst>(LoadUse.getUser())) {
+ // Replace the cmp X, 0 with a use of the bool value.
+ Value *LV = new LoadInst(InitBool, InitBool->getName()
+".val", CI);
+ InitBoolUsed = true;
+ switch (CI->getPredicate()) {
+ default: assert(0 && "Unknown ICmp Predicate!");
+ case FCmpInst::FCMP_OLT:
+ case FCmpInst::FCMP_ULT:
+ case ICmpInst::ICMP_ULT:
+ case ICmpInst::ICMP_SLT:
+ LV = ConstantBool::getFalse(); // X < null -> always
false
+ break;
+ case FCmpInst::FCMP_ULE:
+ case FCmpInst::FCMP_OLE:
+ case FCmpInst::FCMP_OEQ:
+ case FCmpInst::FCMP_UEQ:
+ case ICmpInst::ICMP_ULE:
+ case ICmpInst::ICMP_SLE:
+ case ICmpInst::ICMP_EQ:
+ LV = BinaryOperator::createNot(LV, "notinit", CI);
+ break;
+ case ICmpInst::ICMP_NE:
+ case ICmpInst::ICMP_UGE:
+ case ICmpInst::ICMP_SGE:
+ case ICmpInst::ICMP_UGT:
+ case ICmpInst::ICMP_SGT:
+ case FCmpInst::FCMP_FALSE:
+ case FCmpInst::FCMP_OGT:
+ case FCmpInst::FCMP_OGE:
+ case FCmpInst::FCMP_ONE:
+ case FCmpInst::FCMP_ORD:
+ case FCmpInst::FCMP_UNO:
+ case FCmpInst::FCMP_UGT:
+ case FCmpInst::FCMP_UGE:
+ case FCmpInst::FCMP_UNE:
+ case FCmpInst::FCMP_TRUE:
+ break; // no change.
+ }
+ CI->replaceAllUsesWith(LV);
+ CI->eraseFromParent();
+ }
+ else if (SetCondInst *SCI = dyn_cast<SetCondInst>
(LoadUse.getUser())) {
// Replace the setcc X, 0 with a use of the bool value.
This code is walking the use list of a global variable, so all the FP
cases (including the SetCondInst case) are dead: only pointer
compares are possible.
@@ -746,10 +784,12 @@ static GlobalVariable *OptimizeGlobalAdd
break; // no change.
}
SCI->replaceAllUsesWith(LV);
SCI->eraseFromParent();
}
+ else
+ LoadUse = RepValue;
}
LI->eraseFromParent();
I strongly prefer that you restore this code to its original order.
Putting the short case at the bottom makes it harder to read the
code, even if it makes dyn_cast more natural.
Index: lib/Transforms/ExprTypeConvert.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Transforms/ExprTypeConvert.cpp,v
retrieving revision 1.115
diff -t -d -u -p -5 -r1.115 ExprTypeConvert.cpp
--- lib/Transforms/ExprTypeConvert.cpp 7 Dec 2006 01:30:31 -0000 1.115
+++ lib/Transforms/ExprTypeConvert.cpp 10 Dec 2006 23:26:40 -0000
@@ -456,10 +456,27 @@ static bool OperandConvertibleToType(Use
+ case Instruction::FCmp: {
+ FCmpInst::Predicate pred = cast<FCmpInst>(I)->getPredicate();
+ if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ ||
+ pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE) {
+ Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0);
+ return ExpressionConvertibleToType(OtherOp, Ty, CTMap, TD);
+ }
+ return false;
+ }
case Instruction::SetEQ:
case Instruction::SetNE: {
Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0);
return ExpressionConvertibleToType(OtherOp, Ty, CTMap, TD);
}
This code (FCmp and SetEQ/SetNE) is dead, only integer types can get
this far.
@@ -721,10 +738,37 @@ static void ConvertOperandToType(User *U
...
Res->setOperand(!OtherIdx, NewVal)
;+ case Instruction::FCmp: {
+ FCmpInst::Predicate pred = cast<FCmpInst>(I)->getPredicate();
+ if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ ||
+ pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE) {
+ Res = new FCmpInst(pred, Dummy, Dummy, Name);
+ VMC.ExprMap[I] = Res; // Add node to expression eagerly
+ unsigned OtherIdx = (OldVal == I->getOperand(0)) ? 1 : 0;
+ Value *OtherOp = I->getOperand(OtherIdx);
+ Res->setOperand(!OtherIdx, NewVal);
+ Value *NewOther = ConvertExpressionToType(OtherOp, NewTy,
VMC, TD);
+ Res->setOperand(OtherIdx, NewOther);
+ }
+ break;
+ }
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
assert(I->getOperand(0) == OldVal);
Res = new ShiftInst(cast<ShiftInst>(I)->getOpcode(), NewVal,
Likewise.
-Chris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20061211/a9ef6c50/attachment.html>
More information about the llvm-commits
mailing list