From a78130c3207e59bfb2ec0b77ca3f48677685d9ae Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 20 Apr 2010 05:09:16 +0000 Subject: [PATCH] RewriteLoopBodyWithConditionConstant can end up rewriting the condition we're unswitching on. In this case, don't try to simplify the second copy of the loop which may be dead or not, but is probably a constant now. This fixes PR6879 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101870 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/LoopUnswitch.cpp | 19 ++++++++++++++----- test/Transforms/LoopUnswitch/crash.ll | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp index 3918738cc8b..de124d10aaa 100644 --- a/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -677,15 +677,22 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val, LoopProcessWorklist.push_back(NewLoop); redoLoop = true; + // Keep a WeakVH holding onto LIC. If the first call to RewriteLoopBody + // deletes the instruction (for example by simplifying a PHI that feeds into + // the condition that we're unswitching on), we don't rewrite the second + // iteration. + WeakVH LICHandle(LIC); + // Now we rewrite the original code to know that the condition is true and the // new code to know that the condition is false. RewriteLoopBodyWithConditionConstant(L, LIC, Val, false); - - // It's possible that simplifying one loop could cause the other to be - // deleted. If so, don't simplify it. - if (!LoopProcessWorklist.empty() && LoopProcessWorklist.back() == NewLoop) - RewriteLoopBodyWithConditionConstant(NewLoop, LIC, Val, true); + // It's possible that simplifying one loop could cause the other to be + // changed to another value or a constant. If its a constant, don't simplify + // it. + if (!LoopProcessWorklist.empty() && LoopProcessWorklist.back() == NewLoop && + LICHandle && !isa(LICHandle)) + RewriteLoopBodyWithConditionConstant(NewLoop, LICHandle, Val, true); } /// RemoveFromWorklist - Remove all instances of I from the worklist vector @@ -981,6 +988,8 @@ void LoopUnswitch::SimplifyCode(std::vector &Worklist, Loop *L) { continue; } + // FIXME: Change this to use instruction simplify interfaces! + // Special case hacks that appear commonly in unswitched code. switch (I->getOpcode()) { case Instruction::Select: diff --git a/test/Transforms/LoopUnswitch/crash.ll b/test/Transforms/LoopUnswitch/crash.ll index fac55a6bb1a..101fb7a2c2c 100644 --- a/test/Transforms/LoopUnswitch/crash.ll +++ b/test/Transforms/LoopUnswitch/crash.ll @@ -45,3 +45,22 @@ for.body: ; preds = %for.body, %bb.nph for.end: ; preds = %for.body, %entry ret void } + +; PR6879 +define i32* @test3(i32** %p_45, i16 zeroext %p_46, i64 %p_47, i64 %p_48, i16 signext %p_49) nounwind { +entry: + br label %for.cond + +for.cond: ; preds = %for.cond4, %entry + br i1 false, label %for.cond4, label %for.end88 + +for.cond4: ; preds = %for.cond + %conv46 = trunc i32 0 to i8 ; [#uses=2] + %cmp60 = icmp sgt i8 %conv46, 124 ; [#uses=1] + %or.cond = and i1 undef, %cmp60 ; [#uses=1] + %cond = select i1 %or.cond, i8 %conv46, i8 undef ; [#uses=0] + br label %for.cond + +for.end88: ; preds = %for.cond + ret i32* undef +} -- 2.34.1