From 3df2af21e90e086faa84d866655c9f9de64ccb90 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Wed, 15 Jun 2016 00:19:56 +0000 Subject: [PATCH] [LoopUnroll] Don't crash trying to unroll loop with EH pad exit We do not support splitting cleanuppad or catchswitches. This is problematic for passes which assume that a loop is in loop simplify form (the loop would have a dedicated exit block instead of sharing it). While it isn't great that we don't support this for cleanups, we still cannot make loop-simplify form an assertable precondition because indirectbr will also disable these sorts of CFG cleanups. This fixes PR28132. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272739 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/LoopUnrollPass.cpp | 5 ++ test/Transforms/LoopUnroll/pr28132.ll | 77 ++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 test/Transforms/LoopUnroll/pr28132.ll diff --git a/lib/Transforms/Scalar/LoopUnrollPass.cpp b/lib/Transforms/Scalar/LoopUnrollPass.cpp index 65eab475b69..91af4a1922c 100644 --- a/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -922,6 +922,11 @@ static bool tryToUnrollLoop(Loop *L, DominatorTree &DT, LoopInfo *LI, DEBUG(dbgs() << " Not unrolling loop with inlinable calls.\n"); return false; } + if (!L->isLoopSimplifyForm()) { + DEBUG( + dbgs() << " Not unrolling loop which is not in loop-simplify form.\n"); + return false; + } // Find trip count and trip multiple if count is not available unsigned TripCount = 0; diff --git a/test/Transforms/LoopUnroll/pr28132.ll b/test/Transforms/LoopUnroll/pr28132.ll new file mode 100644 index 00000000000..dc2c0b88023 --- /dev/null +++ b/test/Transforms/LoopUnroll/pr28132.ll @@ -0,0 +1,77 @@ +; RUN: opt -loop-unroll -S < %s | FileCheck %s +target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" +target triple = "i686-pc-windows-msvc" + +declare void @fn1(i8*) + +declare i1 @fn2(i8*, i8*) + +define void @fn4() personality i32 (...)* @__CxxFrameHandler3 { +entry: + br label %for.body + +for.body: ; preds = %for.inc, %entry + %i.05 = phi i8 [ 0, %entry ], [ %inc, %for.inc ] + store i8 undef, i8* undef, align 4 + invoke void @fn1(i8* undef) + to label %call.i.noexc unwind label %ehcleanup + +call.i.noexc: ; preds = %for.body + %call1.i2 = invoke i1 @fn2(i8* undef, i8* undef) + to label %call1.i.noexc unwind label %ehcleanup + +call1.i.noexc: ; preds = %call.i.noexc + br i1 undef, label %if.then.i, label %if.end4.i + +if.then.i: ; preds = %call1.i.noexc + %tmp1 = load i8, i8* undef, align 4 + %tobool.i = icmp eq i8 undef, undef + br i1 undef, label %if.end4.i, label %if.then2.i + +if.then2.i: ; preds = %if.then.i + %call3.i3 = invoke i1 @fn2(i8* undef, i8* null) + to label %call3.i.noexc unwind label %ehcleanup + +call3.i.noexc: ; preds = %if.then2.i + br label %if.end4.i + +if.end4.i: ; preds = %call3.i.noexc, %if.then.i, %call1.i.noexc + %tmp2 = load i8, i8* undef, align 4 + br label %if.then6.i + +if.then6.i: ; preds = %if.end4.i + %call7.i4 = invoke i1 @fn2(i8* undef, i8* null) + to label %call7.i.noexc unwind label %ehcleanup + +call7.i.noexc: ; preds = %if.then6.i + br label %fn3 + +fn3: ; preds = %call7.i.noexc + %tmp3 = load i8, i8* undef, align 4 + %inc.i = add nsw i8 undef, undef + store i8 undef, i8* undef, align 4 + br label %for.inc + +for.inc: ; preds = %fn3 + %inc = add nsw i8 %i.05, 1 + %cmp = icmp slt i8 %inc, 6 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.inc + invoke void @throw() + to label %unreachable unwind label %ehcleanup + +ehcleanup: ; preds = %for.end, %if.then6.i, %if.then2.i, %call.i.noexc, %for.body + %cp = cleanuppad within none [] + cleanupret from %cp unwind to caller + +; CHECK: cleanuppad +; CHECK-NOT: cleanuppad + +unreachable: ; preds = %for.end + unreachable +} + +declare i32 @__CxxFrameHandler3(...) + +declare void @throw()