From 5e058e94b56edf4dfae1c51fcdbbc0ab76b60d41 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Tue, 30 Oct 2007 22:27:26 +0000 Subject: [PATCH] It's not safe to tell SplitCriticalEdge to merge identical edges. It may delete the phi instruction that's being processed. llvm-svn: 43524 --- lib/Transforms/Scalar/LoopStrengthReduce.cpp | 20 ++++---- test/CodeGen/X86/2007-10-30-LSRCrash.ll | 48 ++++++++++++++++++++ 2 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 test/CodeGen/X86/2007-10-30-LSRCrash.ll diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 57ddc67a0a3..e2f1ab6935a 100644 --- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -127,12 +127,12 @@ namespace { /// StrideOrder - An ordering of the keys in IVUsesByStride that is stable: /// We use this to iterate over the IVUsesByStride collection without being /// dependent on random ordering of pointers in the process. - std::vector StrideOrder; + SmallVector StrideOrder; /// CastedValues - As we need to cast values to uintptr_t, this keeps track /// of the casted version of each value. This is accessed by /// getCastedVersionOf. - std::map CastedPointers; + DenseMap CastedPointers; /// DeadInsts - Keep track of instructions we may have made dead, so that /// we can remove them after we are done working. @@ -393,8 +393,7 @@ static bool IVUseShouldUsePostIncValue(Instruction *User, Instruction *IV, // post-incremented value. for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) if (PN->getIncomingValue(i) == IV) { - SplitCriticalEdge(PN->getIncomingBlock(i), PN->getParent(), P, - true); + SplitCriticalEdge(PN->getIncomingBlock(i), PN->getParent(), P, false); // Splitting the critical edge can reduce the number of entries in this // PHI. e = PN->getNumIncomingValues(); @@ -627,7 +626,7 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase, // have multiple entries for the same predecessor. We use a map to make sure // that a PHI node only has a single Value* for each predecessor (which also // prevents us from inserting duplicate code in some blocks). - std::map InsertedCode; + DenseMap InsertedCode; PHINode *PN = cast(Inst); for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { if (PN->getIncomingValue(i) == OperandValToReplace) { @@ -640,7 +639,7 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase, (PN->getParent() != L->getHeader() || !L->contains(PHIPred))) { // First step, split the critical edge. - SplitCriticalEdge(PHIPred, PN->getParent(), P, true); + SplitCriticalEdge(PHIPred, PN->getParent(), P, false); // Next step: move the basic block. In particular, if the PHI node // is outside of the loop, and PredTI is in the loop, we want to @@ -1286,7 +1285,7 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride, // Get a base value. SCEVHandle Base = UsersToProcess[i].Base; - // Compact everything with this base to be consequetive with this one. + // Compact everything with this base to be consequtive with this one. for (unsigned j = i+1; j != e; ++j) { if (UsersToProcess[j].Base == Base) { std::swap(UsersToProcess[i+1], UsersToProcess[j]); @@ -1355,10 +1354,9 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride, // If we are reusing the iv, then it must be multiplied by a constant // factor take advantage of addressing mode scale component. if (RewriteFactor != 0) { - RewriteExpr = - SE->getMulExpr(SE->getIntegerSCEV(RewriteFactor, - RewriteExpr->getType()), - RewriteExpr); + RewriteExpr = SE->getMulExpr(SE->getIntegerSCEV(RewriteFactor, + RewriteExpr->getType()), + RewriteExpr); // The common base is emitted in the loop preheader. But since we // are reusing an IV, it has not been used to initialize the PHI node. diff --git a/test/CodeGen/X86/2007-10-30-LSRCrash.ll b/test/CodeGen/X86/2007-10-30-LSRCrash.ll new file mode 100644 index 00000000000..1c912a01404 --- /dev/null +++ b/test/CodeGen/X86/2007-10-30-LSRCrash.ll @@ -0,0 +1,48 @@ +; RUN: llvm-as < %s | llc -march=x86 + +define i32 @unique(i8* %full, i32 %p, i32 %len, i32 %mode, i32 %verbos, i32 %flags) { +entry: + br i1 false, label %cond_true15, label %cond_next107 + +cond_true15: ; preds = %entry + br i1 false, label %bb98.preheader, label %bb + +bb: ; preds = %cond_true15 + ret i32 0 + +bb98.preheader: ; preds = %cond_true15 + br i1 false, label %bb103, label %bb69.outer + +bb76.split: ; preds = %bb69.outer.split.split, %bb69.us208 + br i1 false, label %bb103, label %bb69.outer + +bb69.outer: ; preds = %bb76.split, %bb98.preheader + %from.0.reg2mem.0.ph.rec = phi i32 [ %tmp75.rec, %bb76.split ], [ 0, %bb98.preheader ] ; [#uses=1] + %tmp75.rec = add i32 %from.0.reg2mem.0.ph.rec, 1 ; [#uses=2] + %tmp75 = getelementptr i8* null, i32 %tmp75.rec ; [#uses=6] + br i1 false, label %bb69.us208, label %bb69.outer.split.split + +bb69.us208: ; preds = %bb69.outer + switch i32 0, label %bb76.split [ + i32 47, label %bb89 + i32 58, label %bb89 + i32 92, label %bb89 + ] + +bb69.outer.split.split: ; preds = %bb69.outer + switch i8 0, label %bb76.split [ + i8 47, label %bb89 + i8 58, label %bb89 + i8 92, label %bb89 + ] + +bb89: ; preds = %bb69.outer.split.split, %bb69.outer.split.split, %bb69.outer.split.split, %bb69.us208, %bb69.us208, %bb69.us208 + %tmp75.lcssa189 = phi i8* [ %tmp75, %bb69.us208 ], [ %tmp75, %bb69.us208 ], [ %tmp75, %bb69.us208 ], [ %tmp75, %bb69.outer.split.split ], [ %tmp75, %bb69.outer.split.split ], [ %tmp75, %bb69.outer.split.split ] ; [#uses=0] + ret i32 0 + +bb103: ; preds = %bb76.split, %bb98.preheader + ret i32 0 + +cond_next107: ; preds = %entry + ret i32 0 +}