From fa0e6facc793d0a67e89f873e18cd35a9d7c02e0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 10 Mar 2011 19:51:54 +0000 Subject: [PATCH] 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 --- lib/Transforms/Scalar/Reassociate.cpp | 14 +++++++++++--- test/Transforms/Reassociate/crash.ll | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index e093b52571a..6a0fb3f7789 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 RankMap; DenseMap, unsigned> ValueRankMap; + SmallVector 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(V); - if (!Op || !isa(Op) || !Op->use_empty()) + if (!Op || !isa(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((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 6f21b66ed00..7a819422eab 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 +} -- 2.34.1