[llvm-commits] [llvm] r158508 - in /llvm/trunk: lib/Transforms/Scalar/Reassociate.cpp test/Transforms/Reassociate/crash.ll
Duncan Sands
baldrick at free.fr
Fri Jun 15 01:37:51 PDT 2012
Author: baldrick
Date: Fri Jun 15 03:37:50 2012
New Revision: 158508
URL: http://llvm.org/viewvc/llvm-project?rev=158508&view=rev
Log:
Fix issues (infinite loop and/or crash) with self-referential instructions, for
example degenerate phi nodes and binops that use themselves in unreachable code.
Thanks to Charles Davis for the testcase that uncovered this can of worms.
Modified:
llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp
llvm/trunk/test/Transforms/Reassociate/crash.ll
Modified: llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp?rev=158508&r1=158507&r2=158508&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp Fri Jun 15 03:37:50 2012
@@ -132,7 +132,7 @@
private:
void BuildRankMap(Function &F);
unsigned getRank(Value *V);
- Value *ReassociateExpression(BinaryOperator *I);
+ void ReassociateExpression(BinaryOperator *I);
void RewriteExprTree(BinaryOperator *I, SmallVectorImpl<ValueEntry> &Ops);
Value *OptimizeExpression(BinaryOperator *I,
SmallVectorImpl<ValueEntry> &Ops);
@@ -1480,12 +1480,14 @@
ValueRankMap.erase(I);
I->eraseFromParent();
// Optimize its operands.
+ SmallPtrSet<Instruction *, 8> Visited; // Detect self-referential nodes.
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
if (Instruction *Op = dyn_cast<Instruction>(Ops[i])) {
// If this is a node in an expression tree, climb to the expression root
// and add that since that's where optimization actually happens.
unsigned Opcode = Op->getOpcode();
- while (Op->hasOneUse() && Op->use_back()->getOpcode() == Opcode)
+ while (Op->hasOneUse() && Op->use_back()->getOpcode() == Opcode &&
+ Visited.insert(Op))
Op = Op->use_back();
RedoInsts.insert(Op);
}
@@ -1585,7 +1587,7 @@
ReassociateExpression(BO);
}
-Value *Reassociate::ReassociateExpression(BinaryOperator *I) {
+void Reassociate::ReassociateExpression(BinaryOperator *I) {
// First, walk the expression tree, linearizing the tree, collecting the
// operand information.
@@ -1612,6 +1614,9 @@
// OptimizeExpression - Now that we have the expression tree in a convenient
// sorted form, optimize it globally if possible.
if (Value *V = OptimizeExpression(I, Ops)) {
+ if (V == I)
+ // Self-referential expression in unreachable code.
+ return;
// This expression tree simplified to something that isn't a tree,
// eliminate it.
DEBUG(dbgs() << "Reassoc to scalar: " << *V << '\n');
@@ -1620,7 +1625,7 @@
VI->setDebugLoc(I->getDebugLoc());
RedoInsts.insert(I);
++NumAnnihil;
- return V;
+ return;
}
// We want to sink immediates as deeply as possible except in the case where
@@ -1638,19 +1643,22 @@
DEBUG(dbgs() << "RAOut:\t"; PrintOps(I, Ops); dbgs() << '\n');
if (Ops.size() == 1) {
+ if (Ops[0].Op == I)
+ // Self-referential expression in unreachable code.
+ return;
+
// This expression tree simplified to something that isn't a tree,
// eliminate it.
I->replaceAllUsesWith(Ops[0].Op);
if (Instruction *OI = dyn_cast<Instruction>(Ops[0].Op))
OI->setDebugLoc(I->getDebugLoc());
RedoInsts.insert(I);
- return Ops[0].Op;
+ return;
}
// Now that we ordered and optimized the expressions, splat them back into
// the expression tree, removing any unneeded nodes.
RewriteExprTree(I, Ops);
- return I;
}
bool Reassociate::runOnFunction(Function &F) {
Modified: llvm/trunk/test/Transforms/Reassociate/crash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Reassociate/crash.ll?rev=158508&r1=158507&r2=158508&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Reassociate/crash.ll (original)
+++ llvm/trunk/test/Transforms/Reassociate/crash.ll Fri Jun 15 03:37:50 2012
@@ -83,3 +83,28 @@
%mul = mul i128 0, 0
ret i128 %mul
}
+
+define void @infinite_loop() {
+entry:
+ br label %loop
+loop:
+ %x = phi i32 [undef, %entry], [%x, %loop]
+ %dead = add i32 %x, 0
+ br label %loop
+unreachable1:
+ %y1 = add i32 %y1, 0
+ %z1 = add i32 %y1, 0
+ ret void
+unreachable2:
+ %y2 = add i32 %y2, 0
+ %z2 = add i32 %y2, %y2
+ ret void
+unreachable3:
+ %y3 = add i32 %y3, %y3
+ %z3 = add i32 %y3, 0
+ ret void
+unreachable4:
+ %y4 = add i32 %y4, %y4
+ %z4 = add i32 %y4, %y4
+ ret void
+}
More information about the llvm-commits
mailing list