From 41ba9f90b7707f41c4602faacde6f0cd352571d6 Mon Sep 17 00:00:00 2001 From: Haicheng Wu Date: Wed, 6 Jul 2016 21:05:40 +0000 Subject: [PATCH] [LIR] Fix mis-compilation with unwinding. To fix PR27859, bail out if there is an instruction may throw. Differential Revision: http://reviews.llvm.org/D20638 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274673 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 8 +++++ test/Transforms/LoopIdiom/unwind.ll | 33 ++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 test/Transforms/LoopIdiom/unwind.ll diff --git a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index a226865262e..ae0c84786e1 100644 --- a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -216,6 +216,14 @@ bool LoopIdiomRecognize::runOnCountableLoop() { << CurLoop->getHeader()->getName() << "\n"); bool MadeChange = false; + + // The following transforms hoist stores/memsets into the loop pre-header. + // Give up if the loop has instructions may throw. + LoopSafetyInfo SafetyInfo; + computeLoopSafetyInfo(&SafetyInfo, CurLoop); + if (SafetyInfo.MayThrow) + return MadeChange; + // Scan all the blocks in the loop that are not in subloops. for (auto *BB : CurLoop->getBlocks()) { // Ignore blocks in subloops. diff --git a/test/Transforms/LoopIdiom/unwind.ll b/test/Transforms/LoopIdiom/unwind.ll new file mode 100644 index 00000000000..a132cba164b --- /dev/null +++ b/test/Transforms/LoopIdiom/unwind.ll @@ -0,0 +1,33 @@ +; RUN: opt -loop-idiom < %s -S | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare void @ff() + +define void @test(i8* noalias nocapture %base, i64 %size) #1 { +entry: + %cmp3 = icmp eq i64 %size, 0 + br i1 %cmp3, label %for.end, label %for.body.preheader + +for.body.preheader: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.preheader, %for.body +; CHECK-LABEL: @test( +; CHECK-NOT: llvm.memset + %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ] + tail call void @ff() + %arrayidx = getelementptr inbounds i8, i8* %base, i64 %indvars.iv + store i8 0, i8* %arrayidx, align 1 + %indvars.iv.next = add i64 %indvars.iv, 1 + %exitcond = icmp ne i64 %indvars.iv.next, %size + br i1 %exitcond, label %for.body, label %for.end.loopexit + +for.end.loopexit: ; preds = %for.body + br label %for.end + +for.end: ; preds = %for.end.loopexit, %entry + ret void +} + +attributes #1 = { uwtable }