From d9fc1ce8096f7138c60edc3a6655583bf209780e Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 10 Apr 2012 05:14:42 +0000 Subject: Fix 12513: Loop unrolling breaks with indirect branches. Take this opportunity to generalize the indirectbr bailout logic for loop transformations. CFG transformations will never get indirectbr right, and there's no point trying. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154386 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../LoopUnroll/2012-04-09-unroll-indirectbr.ll | 40 ++++++++++++++++++++++ .../LoopUnswitch/2012-04-02-IndirectBr.ll | 11 ++---- 2 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 test/Transforms/LoopUnroll/2012-04-09-unroll-indirectbr.ll (limited to 'test') diff --git a/test/Transforms/LoopUnroll/2012-04-09-unroll-indirectbr.ll b/test/Transforms/LoopUnroll/2012-04-09-unroll-indirectbr.ll new file mode 100644 index 0000000000..8946a23c20 --- /dev/null +++ b/test/Transforms/LoopUnroll/2012-04-09-unroll-indirectbr.ll @@ -0,0 +1,40 @@ +; RUN: opt < %s -S -loop-unroll -simplifycfg | FileCheck %s +; PR12513: Loop unrolling breaks with indirect branches. +; If loop unrolling attempts to transform this loop, it replaces the +; indirectbr successors. SimplifyCFG then considers them to be unreachable. +declare void @subtract() nounwind uwtable + +; CHECK-NOT: unreachable +define i32 @main(i32 %argc, i8** nocapture %argv) nounwind uwtable { +entry: + %vals19 = alloca [5 x i32], align 16 + %x20 = alloca i32, align 4 + store i32 135, i32* %x20, align 4 + br label %for.body + +for.body: ; preds = ; %call2_termjoin, %call3_termjoin + %indvars.iv = phi i64 [ 0, %entry ], [ %joinphi15.in.in, %call2_termjoin ] + %a6 = call coldcc i8* @funca(i8* blockaddress(@main, %for.body_code), i8* +blockaddress(@main, %for.body_codeprime)) nounwind + indirectbr i8* %a6, [label %for.body_code, label %for.body_codeprime] + +for.body_code: ; preds = %for.body + call void @subtract() + br label %call2_termjoin + +call2_termjoin: ; preds = %for.body_codeprime, %for.body_code + %joinphi15.in.in = add i64 %indvars.iv, 1 + %exitcond = icmp eq i64 %joinphi15.in.in, 5 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %call2_termjoin + ret i32 0 + +for.body_codeprime: ; preds = %for.body + call void @subtract_v2(i64 %indvars.iv) + br label %call2_termjoin +} + +declare coldcc i8* @funca(i8*, i8*) readonly + +declare void @subtract_v2(i64) nounwind uwtable diff --git a/test/Transforms/LoopUnswitch/2012-04-02-IndirectBr.ll b/test/Transforms/LoopUnswitch/2012-04-02-IndirectBr.ll index c677bde116..c92f0a2be3 100644 --- a/test/Transforms/LoopUnswitch/2012-04-02-IndirectBr.ll +++ b/test/Transforms/LoopUnswitch/2012-04-02-IndirectBr.ll @@ -1,18 +1,13 @@ -; RUN: opt -loop-unswitch -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s -; RUN: opt -S -loop-unswitch -verify-loop-info -verify-dom-info %s | FileCheck %s - -; STATS: 1 loop-unswitch - Total number of instructions analyzed +; RUN: opt < %s -S -loop-unswitch -verify-loop-info -verify-dom-info | FileCheck %s +; PR12343: -loop-unswitch crash on indirect branch ; CHECK: %0 = icmp eq i64 undef, 0 ; CHECK-NEXT: br i1 %0, label %"5", label %"4" ; CHECK: "5": ; preds = %entry -; CHECK-NEXT: br label %"5.split" - -; CHECK: "5.split": ; preds = %"5" ; CHECK-NEXT: br label %"16" -; CHECK: "16": ; preds = %"22", %"5.split" +; CHECK: "16": ; preds = %"22", %"5" ; CHECK-NEXT: indirectbr i8* undef, [label %"22", label %"33"] ; CHECK: "22": ; preds = %"16" -- cgit v1.2.3