aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2011-03-10 19:51:54 +0000
committerDan Gohman <gohman@apple.com>2011-03-10 19:51:54 +0000
commitfa0e6facc793d0a67e89f873e18cd35a9d7c02e0 (patch)
tree9992bf46d1cb90f5a7697ac748938115857b7f13
parenta4f809d8db5222708c9f4519f48916cc919fd19f (diff)
Fix reassociate to postpone certain instruction deletions until
after it has finished all of its reassociations, because its habit of unlinking operands and holding them in a datastructure while working means that it's not easy to determine when an instruction is really dead until after all its regular work is done. rdar://9096268. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127424 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/Reassociate.cpp14
-rw-r--r--test/Transforms/Reassociate/crash.ll25
2 files changed, 36 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp
index e093b52571..6a0fb3f778 100644
--- a/lib/Transforms/Scalar/Reassociate.cpp
+++ b/lib/Transforms/Scalar/Reassociate.cpp
@@ -22,6 +22,7 @@
#define DEBUG_TYPE "reassociate"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
@@ -74,6 +75,7 @@ namespace {
class Reassociate : public FunctionPass {
DenseMap<BasicBlock*, unsigned> RankMap;
DenseMap<AssertingVH<>, unsigned> ValueRankMap;
+ SmallVector<WeakVH, 8> DeadInsts;
bool MadeChange;
public:
static char ID; // Pass identification, replacement for typeid
@@ -113,13 +115,13 @@ FunctionPass *llvm::createReassociatePass() { return new Reassociate(); }
void Reassociate::RemoveDeadBinaryOp(Value *V) {
Instruction *Op = dyn_cast<Instruction>(V);
- if (!Op || !isa<BinaryOperator>(Op) || !Op->use_empty())
+ if (!Op || !isa<BinaryOperator>(Op))
return;
Value *LHS = Op->getOperand(0), *RHS = Op->getOperand(1);
ValueRankMap.erase(Op);
- Op->eraseFromParent();
+ DeadInsts.push_back(Op);
RemoveDeadBinaryOp(LHS);
RemoveDeadBinaryOp(RHS);
}
@@ -603,7 +605,7 @@ Value *Reassociate::RemoveFactorFromExpression(Value *V, Value *Factor) {
// remaining operand.
if (Factors.size() == 1) {
ValueRankMap.erase(BO);
- BO->eraseFromParent();
+ DeadInsts.push_back(BO);
V = Factors[0].Op;
} else {
RewriteExprTree(BO, Factors);
@@ -1093,6 +1095,12 @@ bool Reassociate::runOnFunction(Function &F) {
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
ReassociateBB(FI);
+ // Now that we're done, delete any instructions which are no longer used.
+ while (!DeadInsts.empty())
+ if (Instruction *Inst =
+ cast_or_null<Instruction>((Value *)DeadInsts.pop_back_val()))
+ RecursivelyDeleteTriviallyDeadInstructions(Inst);
+
// We are done with the rank map.
RankMap.clear();
ValueRankMap.clear();
diff --git a/test/Transforms/Reassociate/crash.ll b/test/Transforms/Reassociate/crash.ll
index 6f21b66ed0..7a819422ea 100644
--- a/test/Transforms/Reassociate/crash.ll
+++ b/test/Transforms/Reassociate/crash.ll
@@ -42,3 +42,28 @@ define i32 @test3(i32 %Arg, i32 %x1, i32 %x2, i32 %x3) {
%E = add i32 %D, %C
ret i32 %E
}
+
+
+; rdar://9096268
+define void @x66303361ae3f602889d1b7d0f86e5455(i8* %arg) nounwind {
+_:
+ br label %_33
+
+_33: ; preds = %_33, %_
+ %tmp348 = load i8* %arg, align 1
+ %tmp349 = lshr i8 %tmp348, 7
+ %tmp350 = or i8 %tmp349, 42
+ %tmp351 = add i8 %tmp350, -42
+ %tmp352 = zext i8 %tmp351 to i32
+ %tmp358 = add i32 %tmp352, -501049439
+ %tmp359 = mul i32 %tmp358, %tmp358
+ %tmp360 = mul i32 %tmp352, %tmp352
+ %tmp361 = sub i32 %tmp359, %tmp360
+ %tmp362 = mul i32 %tmp361, -920056735
+ %tmp363 = add i32 %tmp362, 501049439
+ %tmp364 = add i32 %tmp362, -2000262972
+ %tmp365 = sub i32 %tmp363, %tmp364
+ %tmp366 = sub i32 -501049439, %tmp362
+ %tmp367 = add i32 %tmp365, %tmp366
+ br label %_33
+}