Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@ -0,0 +1,20 @@
; This testcase exposed a problem with the loop identification pass (LoopInfo).
; Basically, it was incorrectly calculating the loop nesting information.
;
; RUN: opt < %s -loop-simplify
define i32 @yylex() {
br label %loopentry.0
loopentry.0: ; preds = %else.4, %0
br label %loopexit.2
loopexit.2: ; preds = %else.4, %loopexit.2, %loopentry.0
br i1 false, label %loopexit.2, label %else.4
yy_find_action: ; preds = %else.4
br label %else.4
else.4: ; preds = %yy_find_action, %loopexit.2
switch i32 0, label %loopexit.2 [
i32 2, label %yy_find_action
i32 0, label %loopentry.0
]
}

View File

@ -0,0 +1,42 @@
; This (complex) testcase causes an assertion failure because a preheader is
; inserted for the "fail" loop, but the exit block of a loop is not updated
; to be the preheader instead of the exit loop itself.
; RUN: opt < %s -loop-simplify
define i32 @re_match_2() {
br label %loopentry.1
loopentry.1: ; preds = %endif.82, %0
br label %shortcirc_done.36
shortcirc_done.36: ; preds = %loopentry.1
br i1 false, label %fail, label %endif.40
endif.40: ; preds = %shortcirc_done.36
br label %loopexit.20
loopentry.20: ; preds = %endif.46
br label %loopexit.20
loopexit.20: ; preds = %loopentry.20, %endif.40
br label %loopentry.21
loopentry.21: ; preds = %no_exit.19, %loopexit.20
br i1 false, label %no_exit.19, label %loopexit.21
no_exit.19: ; preds = %loopentry.21
br i1 false, label %fail, label %loopentry.21
loopexit.21: ; preds = %loopentry.21
br label %endif.45
endif.45: ; preds = %loopexit.21
br label %cond_true.15
cond_true.15: ; preds = %endif.45
br i1 false, label %fail, label %endif.46
endif.46: ; preds = %cond_true.15
br label %loopentry.20
fail: ; preds = %loopexit.37, %cond_true.15, %no_exit.19, %shortcirc_done.36
br label %then.80
then.80: ; preds = %fail
br label %endif.81
endif.81: ; preds = %then.80
br label %loopexit.37
loopexit.37: ; preds = %endif.81
br i1 false, label %fail, label %endif.82
endif.82: ; preds = %loopexit.37
br label %loopentry.1
}

View File

@ -0,0 +1,52 @@
; RUN: opt < %s -instcombine -simplifycfg -licm -disable-output
target datalayout = "e-p:32:32"
@yy_base = external global [787 x i16] ; <[787 x i16]*> [#uses=1]
@yy_state_ptr = external global i32* ; <i32**> [#uses=3]
@yy_state_buf = external global [16386 x i32] ; <[16386 x i32]*> [#uses=1]
@yy_lp = external global i32 ; <i32*> [#uses=1]
define i32 @_yylex() {
br label %loopentry.0
loopentry.0: ; preds = %else.26, %0
store i32* getelementptr ([16386 x i32], [16386 x i32]* @yy_state_buf, i64 0, i64 0), i32** @yy_state_ptr
%tmp.35 = load i32*, i32** @yy_state_ptr ; <i32*> [#uses=2]
%inc.0 = getelementptr i32, i32* %tmp.35, i64 1 ; <i32*> [#uses=1]
store i32* %inc.0, i32** @yy_state_ptr
%tmp.36 = load i32, i32* null ; <i32> [#uses=1]
store i32 %tmp.36, i32* %tmp.35
br label %loopexit.2
loopexit.2: ; preds = %else.26, %loopexit.2, %loopentry.0
store i8* null, i8** null
%tmp.91 = load i32, i32* null ; <i32> [#uses=1]
%tmp.92 = sext i32 %tmp.91 to i64 ; <i64> [#uses=1]
%tmp.93 = getelementptr [787 x i16], [787 x i16]* @yy_base, i64 0, i64 %tmp.92 ; <i16*> [#uses=1]
%tmp.94 = load i16, i16* %tmp.93 ; <i16> [#uses=1]
%tmp.95 = icmp ne i16 %tmp.94, 4394 ; <i1> [#uses=1]
br i1 %tmp.95, label %loopexit.2, label %yy_find_action
yy_find_action: ; preds = %else.26, %loopexit.2
br label %loopentry.3
loopentry.3: ; preds = %then.9, %shortcirc_done.0, %yy_find_action
%tmp.105 = load i32, i32* @yy_lp ; <i32> [#uses=1]
%tmp.106 = icmp ne i32 %tmp.105, 0 ; <i1> [#uses=1]
br i1 %tmp.106, label %shortcirc_next.0, label %shortcirc_done.0
shortcirc_next.0: ; preds = %loopentry.3
%tmp.114 = load i16, i16* null ; <i16> [#uses=1]
%tmp.115 = sext i16 %tmp.114 to i32 ; <i32> [#uses=1]
%tmp.116 = icmp slt i32 0, %tmp.115 ; <i1> [#uses=1]
br label %shortcirc_done.0
shortcirc_done.0: ; preds = %shortcirc_next.0, %loopentry.3
%shortcirc_val.0 = phi i1 [ false, %loopentry.3 ], [ %tmp.116, %shortcirc_next.0 ] ; <i1> [#uses=1]
br i1 %shortcirc_val.0, label %else.0, label %loopentry.3
else.0: ; preds = %shortcirc_done.0
%tmp.144 = load i32, i32* null ; <i32> [#uses=1]
%tmp.145 = and i32 %tmp.144, 8192 ; <i32> [#uses=1]
%tmp.146 = icmp ne i32 %tmp.145, 0 ; <i1> [#uses=1]
br i1 %tmp.146, label %then.9, label %else.26
then.9: ; preds = %else.0
br label %loopentry.3
else.26: ; preds = %else.0
switch i32 0, label %loopentry.0 [
i32 2, label %yy_find_action
i32 0, label %loopexit.2
]
}

View File

@ -0,0 +1,36 @@
; LoopSimplify is breaking LICM on this testcase because the exit blocks from
; the loop are reachable from more than just the exit nodes: the exit blocks
; have predecessors from outside of the loop!
;
; This is distilled from a monsterous crafty example.
; RUN: opt < %s -licm -disable-output
@G = weak global i32 0 ; <i32*> [#uses=7]
define i32 @main() {
entry:
store i32 123, i32* @G
br label %loopentry.i
loopentry.i: ; preds = %endif.1.i, %entry
%tmp.0.i = load i32, i32* @G ; <i32> [#uses=1]
%tmp.1.i = icmp eq i32 %tmp.0.i, 123 ; <i1> [#uses=1]
br i1 %tmp.1.i, label %Out.i, label %endif.0.i
endif.0.i: ; preds = %loopentry.i
%tmp.3.i = load i32, i32* @G ; <i32> [#uses=1]
%tmp.4.i = icmp eq i32 %tmp.3.i, 126 ; <i1> [#uses=1]
br i1 %tmp.4.i, label %ExitBlock.i, label %endif.1.i
endif.1.i: ; preds = %endif.0.i
%tmp.6.i = load i32, i32* @G ; <i32> [#uses=1]
%inc.i = add i32 %tmp.6.i, 1 ; <i32> [#uses=1]
store i32 %inc.i, i32* @G
br label %loopentry.i
Out.i: ; preds = %loopentry.i
store i32 0, i32* @G
br label %ExitBlock.i
ExitBlock.i: ; preds = %Out.i, %endif.0.i
%tmp.7.i = load i32, i32* @G ; <i32> [#uses=1]
ret i32 %tmp.7.i
}

View File

@ -0,0 +1,14 @@
; RUN: opt < %s -loop-simplify -verify -licm -disable-output
define void @.subst_48() {
entry:
br label %loopentry.0
loopentry.0: ; preds = %loopentry.0, %entry
br i1 false, label %loopentry.0, label %loopentry.2
loopentry.2: ; preds = %loopentry.2, %loopentry.0
%tmp.968 = icmp sle i32 0, 3 ; <i1> [#uses=1]
br i1 %tmp.968, label %loopentry.2, label %UnifiedReturnBlock
UnifiedReturnBlock: ; preds = %loopentry.2
ret void
}

View File

@ -0,0 +1,11 @@
; RUN: opt < %s -loop-simplify -licm -disable-output
define void @main() {
entry:
br i1 false, label %Out, label %loop
loop: ; preds = %loop, %entry
%LI = icmp sgt i32 0, 0 ; <i1> [#uses=1]
br i1 %LI, label %loop, label %Out
Out: ; preds = %loop, %entry
ret void
}

View File

@ -0,0 +1,20 @@
; RUN: opt < %s -loop-simplify -licm -disable-output
; This is PR306
define void @NormalizeCoeffsVecFFE() {
entry:
br label %loopentry.0
loopentry.0: ; preds = %no_exit.0, %entry
br i1 false, label %loopentry.1, label %no_exit.0
no_exit.0: ; preds = %loopentry.0
br i1 false, label %loopentry.0, label %loopentry.1
loopentry.1: ; preds = %no_exit.1, %no_exit.0, %loopentry.0
br i1 false, label %no_exit.1, label %loopexit.1
no_exit.1: ; preds = %loopentry.1
%tmp.43 = icmp eq i16 0, 0 ; <i1> [#uses=1]
br i1 %tmp.43, label %loopentry.1, label %loopexit.1
loopexit.1: ; preds = %no_exit.1, %loopentry.1
ret void
}

View File

@ -0,0 +1,18 @@
; RUN: opt < %s -loop-simplify -disable-output
define void @test() {
loopentry.0:
br label %loopentry.1
loopentry.1: ; preds = %then.6, %then.6, %loopentry.1, %loopentry.0
%pixel.4 = phi i32 [ 0, %loopentry.0 ], [ %pixel.4, %loopentry.1 ], [ %tmp.370, %then.6 ], [ %tmp.370, %then.6 ] ; <i32> [#uses=1]
br i1 false, label %then.6, label %loopentry.1
then.6: ; preds = %loopentry.1
%tmp.370 = add i32 0, 0 ; <i32> [#uses=2]
switch i32 0, label %label.7 [
i32 6408, label %loopentry.1
i32 32841, label %loopentry.1
]
label.7: ; preds = %then.6
ret void
}

View File

@ -0,0 +1,18 @@
; RUN: opt < %s -sroa -loop-simplify -licm -disable-output -verify-dom-info -verify-loop-info
define void @inflate() {
entry:
br label %loopentry.0.outer1111
loopentry.0.outer1111: ; preds = %then.41, %label.11, %loopentry.0.outer1111, %entry
%left.0.ph1107 = phi i32 [ %tmp.1172, %then.41 ], [ 0, %entry ], [ %tmp.1172, %label.11 ], [ %left.0.ph1107, %loopentry.0.outer1111 ] ; <i32> [#uses=2]
%tmp.1172 = sub i32 %left.0.ph1107, 0 ; <i32> [#uses=2]
switch i32 0, label %label.11 [
i32 23, label %loopentry.0.outer1111
i32 13, label %then.41
]
label.11: ; preds = %loopentry.0.outer1111
br label %loopentry.0.outer1111
then.41: ; preds = %loopentry.0.outer1111
br label %loopentry.0.outer1111
}

View File

@ -0,0 +1,29 @@
; RUN: opt < %s -loop-simplify -disable-output
; PR1752
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-s0:0:64-f80:32:32"
target triple = "i686-pc-mingw32"
define void @func() personality i32 (...)* @__gxx_personality_v0 {
bb_init:
br label %bb_main
bb_main:
br label %invcont17.normaldest
invcont17.normaldest917: ; No predecessors!
%tmp23 = invoke i32 @foo()
to label %invcont17.normaldest unwind label %invcont17.normaldest.normaldest
invcont17.normaldest: ; preds = %invcont17.normaldest917, %bb_main
br label %bb_main
invcont17.normaldest.normaldest: ; No predecessors!
%exn = landingpad {i8*, i32}
catch i8* null
store i32 %tmp23, i32* undef
br label %bb_main
}
declare i32 @foo()
declare i32 @__gxx_personality_v0(...)

View File

@ -0,0 +1,20 @@
; RUN: opt < %s -domfrontier -loop-simplify -domfrontier -verify-dom-info -analyze
define void @a() nounwind {
entry:
br i1 undef, label %bb37, label %bb1.i
bb1.i: ; preds = %bb1.i, %bb
%indvar = phi i64 [ %indvar.next, %bb1.i ], [ 0, %entry ] ; <i64> [#uses=1]
%indvar.next = add i64 %indvar, 1 ; <i64> [#uses=2]
%exitcond = icmp eq i64 %indvar.next, 576 ; <i1> [#uses=1]
br i1 %exitcond, label %bb37, label %bb1.i
bb37: ; preds = %bb1.i, %bb
br label %return
return: ; preds = %bb39
ret void
}

View File

@ -0,0 +1,43 @@
; RUN: opt < %s -loop-simplify -S
; PR8702
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-unknown-freebsd9.0"
declare void @foo(i32 %x)
define fastcc void @inm_merge() nounwind {
entry:
br label %for.cond
for.cond: ; preds = %while.cond36.i, %entry
br i1 undef, label %do.body, label %for.body
for.body: ; preds = %for.cond
br i1 undef, label %while.cond36.i, label %if.end44
if.end44: ; preds = %for.body
%call49 = call fastcc i32 @inm_get_source()
br i1 undef, label %if.end54, label %for.cond64
if.end54: ; preds = %if.end44
br label %while.cond36.i
while.cond36.i: ; preds = %if.end54, %for.body
br label %for.cond
for.cond64: ; preds = %if.end88, %for.cond64, %if.end44
%error.161 = phi i32 [ %error.161, %for.cond64 ], [ %error.161, %if.end88 ], [ %call49, %if.end44 ]
call void @foo(i32 %error.161)
br i1 undef, label %for.cond64, label %if.end88
if.end88: ; preds = %for.cond64
br i1 undef, label %for.cond64, label %if.end98
if.end98: ; preds = %if.end88
unreachable
do.body: ; preds = %for.cond
unreachable
}
declare fastcc i32 @inm_get_source() nounwind

View File

@ -0,0 +1,45 @@
; RUN: opt < %s -loop-simplify -S | FileCheck %s
; PR11575
@catchtypeinfo = external unnamed_addr constant { i8*, i8*, i8* }
define void @main() uwtable ssp personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
entry:
invoke void @f1()
to label %try.cont19 unwind label %catch
; CHECK: catch.preheader:
; CHECK-NEXT: landingpad
; CHECK: br label %catch
; CHECK: catch.preheader.split-lp:
; CHECK-NEXT: landingpad
; CHECK: br label %catch
catch: ; preds = %if.else, %entry
%0 = landingpad { i8*, i32 }
catch i8* bitcast ({ i8*, i8*, i8* }* @catchtypeinfo to i8*)
invoke void @f3()
to label %if.else unwind label %eh.resume
if.else: ; preds = %catch
invoke void @f2()
to label %try.cont19 unwind label %catch
try.cont19: ; preds = %if.else, %entry
ret void
eh.resume: ; preds = %catch
%1 = landingpad { i8*, i32 }
cleanup
catch i8* bitcast ({ i8*, i8*, i8* }* @catchtypeinfo to i8*)
resume { i8*, i32 } undef
}
declare i32 @__gxx_personality_v0(...)
declare void @f1()
declare void @f2()
declare void @f3()

View File

@ -0,0 +1,41 @@
; RUN: opt < %s -loop-simplify -S | FileCheck %s
; Make sure the preheader exists.
; CHECK: sw.bb103:
; CHECK: indirectbr {{.*}}label %while.cond112
; CHECK: while.cond112:
; But the tail is not split.
; CHECK: for.body:
; CHECK: indirectbr {{.*}}label %while.cond112
define fastcc void @build_regex_nfa() nounwind uwtable ssp {
entry:
indirectbr i8* blockaddress(@build_regex_nfa, %while.cond), [label %while.cond]
while.cond: ; preds = %if.then439, %entry
indirectbr i8* blockaddress(@build_regex_nfa, %sw.bb103), [label %do.body785, label %sw.bb103]
sw.bb103: ; preds = %while.body
indirectbr i8* blockaddress(@build_regex_nfa, %while.cond112), [label %while.cond112]
while.cond112: ; preds = %for.body, %for.cond.preheader, %sw.bb103
%pc.0 = phi i8 [ -1, %sw.bb103 ], [ 0, %for.body ], [ %pc.0, %for.cond.preheader ]
indirectbr i8* blockaddress(@build_regex_nfa, %Lsetdone), [label %sw.bb118, label %Lsetdone]
sw.bb118: ; preds = %while.cond112
indirectbr i8* blockaddress(@build_regex_nfa, %for.cond.preheader), [label %Lerror.loopexit, label %for.cond.preheader]
for.cond.preheader: ; preds = %sw.bb118
indirectbr i8* blockaddress(@build_regex_nfa, %for.body), [label %while.cond112, label %for.body]
for.body: ; preds = %for.body, %for.cond.preheader
indirectbr i8* blockaddress(@build_regex_nfa, %for.body), [label %while.cond112, label %for.body]
Lsetdone: ; preds = %while.cond112
unreachable
do.body785: ; preds = %while.cond, %while.body
ret void
Lerror.loopexit: ; preds = %sw.bb118
unreachable
}

View File

@ -0,0 +1,80 @@
; RUN: opt -basicaa -loop-rotate -licm -instcombine -indvars -loop-unroll -S %s | FileCheck %s
;
; PR18361: ScalarEvolution::getAddRecExpr():
; Assertion `isLoopInvariant(Operands[i],...
;
; After a series of loop optimizations, SCEV's LoopDispositions grow stale.
; In particular, LoopSimplify hoists %cmp4, resulting in this SCEV for %add:
; {(zext i1 %cmp4 to i32),+,1}<nw><%for.cond1.preheader>
;
; When recomputing the SCEV for %ashr, we truncate the operands to get:
; (zext i1 %cmp4 to i16)
;
; This SCEV was never mapped to a value so never invalidated. It's
; loop disposition is still marked as non-loop-invariant, which is
; inconsistent with the AddRec.
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx"
@d = common global i32 0, align 4
@a = common global i32 0, align 4
@c = common global i32 0, align 4
@b = common global i32 0, align 4
; Check that the def-use chain that leads to the bad SCEV is still
; there.
;
; CHECK-LABEL: @foo
; CHECK-LABEL: entry:
; CHECK-LABEL: for.cond1.preheader:
; CHECK-LABEL: for.body3:
; CHECK: %cmp4.le.le
; CHECK: %conv.le.le = zext i1 %cmp4.le.le to i32
; CHECK: %xor.le.le = xor i32 %conv6.le.le, 1
define void @foo() {
entry:
br label %for.cond
for.cond: ; preds = %for.inc7, %entry
%storemerge = phi i32 [ 0, %entry ], [ %inc8, %for.inc7 ]
%f.0 = phi i32 [ undef, %entry ], [ %f.1, %for.inc7 ]
store i32 %storemerge, i32* @d, align 4
%cmp = icmp slt i32 %storemerge, 1
br i1 %cmp, label %for.cond1, label %for.end9
for.cond1: ; preds = %for.cond, %for.body3
%storemerge1 = phi i32 [ %inc, %for.body3 ], [ 0, %for.cond ]
%f.1 = phi i32 [ %xor, %for.body3 ], [ %f.0, %for.cond ]
store i32 %storemerge1, i32* @a, align 4
%cmp2 = icmp slt i32 %storemerge1, 1
br i1 %cmp2, label %for.body3, label %for.inc7
for.body3: ; preds = %for.cond1
%0 = load i32, i32* @c, align 4
%cmp4 = icmp sge i32 %storemerge1, %0
%conv = zext i1 %cmp4 to i32
%1 = load i32, i32* @d, align 4
%add = add nsw i32 %conv, %1
%sext = shl i32 %add, 16
%conv6 = ashr exact i32 %sext, 16
%xor = xor i32 %conv6, 1
%inc = add nsw i32 %storemerge1, 1
br label %for.cond1
for.inc7: ; preds = %for.cond1
%2 = load i32, i32* @d, align 4
%inc8 = add nsw i32 %2, 1
br label %for.cond
for.end9: ; preds = %for.cond
%cmp10 = icmp sgt i32 %f.0, 0
br i1 %cmp10, label %if.then, label %if.end
if.then: ; preds = %for.end9
store i32 0, i32* @b, align 4
br label %if.end
if.end: ; preds = %if.then, %for.end9
ret void
}

View File

@ -0,0 +1,236 @@
; RUN: opt < %s -S -loop-simplify | FileCheck %s
; RUN: opt < %s -S -passes=loop-simplify | FileCheck %s
; This function should get a preheader inserted before bb3, that is jumped
; to by bb1 & bb2
define void @test() {
; CHECK-LABEL: define void @test(
entry:
br i1 true, label %bb1, label %bb2
bb1:
br label %bb3
; CHECK: bb1:
; CHECK-NEXT: br label %[[PH:.*]]
bb2:
br label %bb3
; CHECK: bb2:
; CHECK-NEXT: br label %[[PH]]
bb3:
br label %bb3
; CHECK: [[PH]]:
; CHECK-NEXT: br label %bb3
;
; CHECK: bb3:
; CHECK-NEXT: br label %bb3
}
; Test a case where we have multiple exit blocks as successors of a single loop
; block that need to be made dedicated exit blocks. We also have multiple
; exiting edges to one of the exit blocks that all should be rewritten.
define void @test_multiple_exits_from_single_block(i8 %a, i8* %b.ptr) {
; CHECK-LABEL: define void @test_multiple_exits_from_single_block(
entry:
switch i8 %a, label %loop [
i8 0, label %exit.a
i8 1, label %exit.b
]
; CHECK: entry:
; CHECK-NEXT: switch i8 %a, label %[[PH:.*]] [
; CHECK-NEXT: i8 0, label %exit.a
; CHECK-NEXT: i8 1, label %exit.b
; CHECK-NEXT: ]
loop:
%b = load volatile i8, i8* %b.ptr
switch i8 %b, label %loop [
i8 0, label %exit.a
i8 1, label %exit.b
i8 2, label %loop
i8 3, label %exit.a
i8 4, label %loop
i8 5, label %exit.a
i8 6, label %loop
]
; CHECK: [[PH]]:
; CHECK-NEXT: br label %loop
;
; CHECK: loop:
; CHECK-NEXT: %[[B:.*]] = load volatile i8, i8* %b.ptr
; CHECK-NEXT: switch i8 %[[B]], label %[[BACKEDGE:.*]] [
; CHECK-NEXT: i8 0, label %[[LOOPEXIT_A:.*]]
; CHECK-NEXT: i8 1, label %[[LOOPEXIT_B:.*]]
; CHECK-NEXT: i8 2, label %[[BACKEDGE]]
; CHECK-NEXT: i8 3, label %[[LOOPEXIT_A]]
; CHECK-NEXT: i8 4, label %[[BACKEDGE]]
; CHECK-NEXT: i8 5, label %[[LOOPEXIT_A]]
; CHECK-NEXT: i8 6, label %[[BACKEDGE]]
; CHECK-NEXT: ]
;
; CHECK: [[BACKEDGE]]:
; CHECK-NEXT: br label %loop
exit.a:
ret void
; CHECK: [[LOOPEXIT_A]]:
; CHECK-NEXT: br label %exit.a
;
; CHECK: exit.a:
; CHECK-NEXT: ret void
exit.b:
ret void
; CHECK: [[LOOPEXIT_B]]:
; CHECK-NEXT: br label %exit.b
;
; CHECK: exit.b:
; CHECK-NEXT: ret void
}
; Check that we leave already dedicated exits alone when forming dedicated exit
; blocks.
define void @test_pre_existing_dedicated_exits(i1 %a, i1* %ptr) {
; CHECK-LABEL: define void @test_pre_existing_dedicated_exits(
entry:
br i1 %a, label %loop.ph, label %non_dedicated_exit
; CHECK: entry:
; CHECK-NEXT: br i1 %a, label %loop.ph, label %non_dedicated_exit
loop.ph:
br label %loop.header
; CHECK: loop.ph:
; CHECK-NEXT: br label %loop.header
loop.header:
%c1 = load volatile i1, i1* %ptr
br i1 %c1, label %loop.body1, label %dedicated_exit1
; CHECK: loop.header:
; CHECK-NEXT: %[[C1:.*]] = load volatile i1, i1* %ptr
; CHECK-NEXT: br i1 %[[C1]], label %loop.body1, label %dedicated_exit1
loop.body1:
%c2 = load volatile i1, i1* %ptr
br i1 %c2, label %loop.body2, label %non_dedicated_exit
; CHECK: loop.body1:
; CHECK-NEXT: %[[C2:.*]] = load volatile i1, i1* %ptr
; CHECK-NEXT: br i1 %[[C2]], label %loop.body2, label %[[LOOPEXIT:.*]]
loop.body2:
%c3 = load volatile i1, i1* %ptr
br i1 %c3, label %loop.backedge, label %dedicated_exit2
; CHECK: loop.body2:
; CHECK-NEXT: %[[C3:.*]] = load volatile i1, i1* %ptr
; CHECK-NEXT: br i1 %[[C3]], label %loop.backedge, label %dedicated_exit2
loop.backedge:
br label %loop.header
; CHECK: loop.backedge:
; CHECK-NEXT: br label %loop.header
dedicated_exit1:
ret void
; Check that there isn't a split loop exit.
; CHECK-NOT: br label %dedicated_exit1
;
; CHECK: dedicated_exit1:
; CHECK-NEXT: ret void
dedicated_exit2:
ret void
; Check that there isn't a split loop exit.
; CHECK-NOT: br label %dedicated_exit2
;
; CHECK: dedicated_exit2:
; CHECK-NEXT: ret void
non_dedicated_exit:
ret void
; CHECK: [[LOOPEXIT]]:
; CHECK-NEXT: br label %non_dedicated_exit
;
; CHECK: non_dedicated_exit:
; CHECK-NEXT: ret void
}
; Check that we form what dedicated exits we can even when some exits are
; reached via indirectbr which precludes forming dedicated exits.
define void @test_form_some_dedicated_exits_despite_indirectbr(i8 %a, i8* %ptr, i8** %addr.ptr) {
; CHECK-LABEL: define void @test_form_some_dedicated_exits_despite_indirectbr(
entry:
switch i8 %a, label %loop.ph [
i8 0, label %exit.a
i8 1, label %exit.b
i8 2, label %exit.c
]
; CHECK: entry:
; CHECK-NEXT: switch i8 %a, label %loop.ph [
; CHECK-NEXT: i8 0, label %exit.a
; CHECK-NEXT: i8 1, label %exit.b
; CHECK-NEXT: i8 2, label %exit.c
; CHECK-NEXT: ]
loop.ph:
br label %loop.header
; CHECK: loop.ph:
; CHECK-NEXT: br label %loop.header
loop.header:
%addr1 = load volatile i8*, i8** %addr.ptr
indirectbr i8* %addr1, [label %loop.body1, label %exit.a]
; CHECK: loop.header:
; CHECK-NEXT: %[[ADDR1:.*]] = load volatile i8*, i8** %addr.ptr
; CHECK-NEXT: indirectbr i8* %[[ADDR1]], [label %loop.body1, label %exit.a]
loop.body1:
%b = load volatile i8, i8* %ptr
switch i8 %b, label %loop.body2 [
i8 0, label %exit.a
i8 1, label %exit.b
i8 2, label %exit.c
]
; CHECK: loop.body1:
; CHECK-NEXT: %[[B:.*]] = load volatile i8, i8* %ptr
; CHECK-NEXT: switch i8 %[[B]], label %loop.body2 [
; CHECK-NEXT: i8 0, label %exit.a
; CHECK-NEXT: i8 1, label %[[LOOPEXIT:.*]]
; CHECK-NEXT: i8 2, label %exit.c
; CHECK-NEXT: ]
loop.body2:
%addr2 = load volatile i8*, i8** %addr.ptr
indirectbr i8* %addr2, [label %loop.backedge, label %exit.c]
; CHECK: loop.body2:
; CHECK-NEXT: %[[ADDR2:.*]] = load volatile i8*, i8** %addr.ptr
; CHECK-NEXT: indirectbr i8* %[[ADDR2]], [label %loop.backedge, label %exit.c]
loop.backedge:
br label %loop.header
; CHECK: loop.backedge:
; CHECK-NEXT: br label %loop.header
exit.a:
ret void
; Check that there isn't a split loop exit.
; CHECK-NOT: br label %exit.a
;
; CHECK: exit.a:
; CHECK-NEXT: ret void
exit.b:
ret void
; CHECK: [[LOOPEXIT]]:
; CHECK-NEXT: br label %exit.b
;
; CHECK: exit.b:
; CHECK-NEXT: ret void
exit.c:
ret void
; Check that there isn't a split loop exit.
; CHECK-NOT: br label %exit.c
;
; CHECK: exit.c:
; CHECK-NEXT: ret void
}

View File

@ -0,0 +1,102 @@
; Check that LoopSimplify creates debug locations in synthesized basic blocks.
; RUN: opt -loop-simplify %s -S -o - | FileCheck %s
%union.anon = type { i32 }
%"Length" = type <{ %union.anon, i8, i8, i8, i8 }>
declare void @bar(%"Length"*) #3
@catchtypeinfo = external unnamed_addr constant { i8*, i8*, i8* }
declare i32 @__gxx_personality_v0(...)
declare void @f1()
declare void @f2()
declare void @f3()
; CHECK-LABEL: @foo
; CHECK: for.body.preheader:
; CHECK-NEXT: br label %for.body, !dbg [[PREHEADER_LOC:![0-9]+]]
; CHECK: for.end.loopexit:
; CHECK-NEXT: br label %for.end, !dbg [[LOOPEXIT_LOC:![0-9]+]]
define linkonce_odr hidden void @foo(%"Length"* %begin, %"Length"* %end) nounwind ssp uwtable align 2 !dbg !6 {
entry:
%cmp.4 = icmp eq %"Length"* %begin, %end, !dbg !7
br i1 %cmp.4, label %for.end, label %for.body, !dbg !8
for.body: ; preds = %entry, %length.exit
%begin.sink5 = phi %"Length"* [ %incdec.ptr, %length.exit ], [ %begin, %entry ]
tail call void @llvm.dbg.value(metadata %"Length"* %begin.sink5, metadata !15, metadata !16), !dbg !17
%m_type.i.i.i = getelementptr inbounds %"Length", %"Length"* %begin.sink5, i64 0, i32 2, !dbg !9
%0 = load i8, i8* %m_type.i.i.i, align 1, !dbg !9
%cmp.i.i = icmp eq i8 %0, 9, !dbg !7
br i1 %cmp.i.i, label %if.then.i, label %length.exit, !dbg !8
if.then.i: ; preds = %for.body
tail call void @bar(%"Length"* %begin.sink5) #7, !dbg !10
br label %length.exit, !dbg !10
length.exit: ; preds = %for.body, %if.then.i
%incdec.ptr = getelementptr inbounds %"Length", %"Length"* %begin.sink5, i64 1, !dbg !11
%cmp = icmp eq %"Length"* %incdec.ptr, %end, !dbg !7
br i1 %cmp, label %for.end, label %for.body, !dbg !8
for.end: ; preds = %length.exit, %entry
ret void, !dbg !12
}
; CHECK-LABEL: @with_landingpad
; CHECK: catch.preheader:
; CHECK: br label %catch, !dbg [[LPAD_PREHEADER_LOC:![0-9]+]]
; CHECK: catch.preheader.split-lp:
; CHECK: br label %catch, !dbg [[LPAD_PREHEADER_LOC]]
define void @with_landingpad() uwtable ssp personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
entry:
invoke void @f1() to label %try.cont19 unwind label %catch, !dbg !13
catch: ; preds = %if.else, %entry
%0 = landingpad { i8*, i32 }
catch i8* bitcast ({ i8*, i8*, i8* }* @catchtypeinfo to i8*), !dbg !13
invoke void @f3() to label %if.else unwind label %eh.resume, !dbg !13
if.else: ; preds = %catch
invoke void @f2() to label %try.cont19 unwind label %catch, !dbg !13
try.cont19: ; preds = %if.else, %entry
ret void, !dbg !13
eh.resume: ; preds = %catch
%1 = landingpad { i8*, i32 }
cleanup catch i8* bitcast ({ i8*, i8*, i8* }* @catchtypeinfo to i8*), !dbg !13
resume { i8*, i32 } undef, !dbg !13
}
; Function Attrs: nounwind readnone
declare void @llvm.dbg.value(metadata, metadata, metadata)
; CHECK-DAG: [[PREHEADER_LOC]] = !DILocation(line: 73, column: 27, scope: !{{[0-9]+}})
; CHECK-DAG: [[LOOPEXIT_LOC]] = !DILocation(line: 75, column: 9, scope: !{{[0-9]+}})
; CHECK-DAG: [[LPAD_PREHEADER_LOC]] = !DILocation(line: 85, column: 1, scope: !{{[0-9]+}})
!llvm.module.flags = !{!0, !1, !2}
!llvm.dbg.cu = !{!14}
!0 = !{i32 2, !"Dwarf Version", i32 4}
!1 = !{i32 2, !"Debug Info Version", i32 3}
!2 = !{i32 1, !"PIC Level", i32 2}
!3 = !{}
!4 = !DISubroutineType(types: !3)
!5 = !DIFile(filename: "Vector.h", directory: "/tmp")
!6 = distinct !DISubprogram(name: "destruct", scope: !5, file: !5, line: 71, type: !4, isLocal: false, isDefinition: true, scopeLine: 72, flags: DIFlagPrototyped, isOptimized: false, unit: !14, variables: !3)
!7 = !DILocation(line: 73, column: 38, scope: !6)
!8 = !DILocation(line: 73, column: 13, scope: !6)
!9 = !DILocation(line: 73, column: 27, scope: !6)
!10 = !DILocation(line: 74, column: 17, scope: !6)
!11 = !DILocation(line: 73, column: 46, scope: !6)
!12 = !DILocation(line: 75, column: 9, scope: !6)
!13 = !DILocation(line: 85, column: 1, scope: !6)
!14 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang",
file: !5,
isOptimized: true, flags: "-O2",
splitDebugFilename: "abc.debug", emissionKind: 2)
!15 = !DILocalVariable(name: "begin", arg: 1, scope: !6, file: !5, line: 71)
!16 = !DIExpression()
!17 = !DILocation(line: 71, column: 32, scope: !6)

View File

@ -0,0 +1,46 @@
; RUN: opt -loop-simplify -S %s | FileCheck %s
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
target triple = "powerpc64-bgq-linux"
define fastcc void @do_update_md([3 x float]* nocapture readonly %x) #0 {
entry:
br i1 undef, label %if.end365, label %lor.lhs.false134
lor.lhs.false134: ; preds = %entry
br i1 undef, label %lor.lhs.false138, label %if.end365
lor.lhs.false138: ; preds = %lor.lhs.false134
br i1 undef, label %lor.lhs.false142, label %if.end365
lor.lhs.false142: ; preds = %lor.lhs.false138
br i1 undef, label %for.body276.lr.ph, label %if.end365
for.body276.lr.ph: ; preds = %lor.lhs.false142
switch i16 undef, label %if.then288 [
i16 4, label %for.body344
i16 2, label %for.body344
]
if.then288: ; preds = %for.body276.lr.ph
br label %for.body305
for.body305: ; preds = %for.body305, %if.then288
br label %for.body305
for.body344: ; preds = %for.body344, %for.body276.lr.ph, %for.body276.lr.ph
%indvar = phi i64 [ %indvar.next, %for.body344 ], [ 0, %for.body276.lr.ph ], [ 0, %for.body276.lr.ph ]
%indvars.iv552 = phi i64 [ %indvars.iv.next553, %for.body344 ], [ 0, %for.body276.lr.ph ], [ 0, %for.body276.lr.ph ]
%indvars.iv.next553 = add nuw nsw i64 %indvars.iv552, 1
%indvar.next = add i64 %indvar, 1
br label %for.body344
; CHECK-LABEL: @do_update_md
; CHECK: %indvars.iv552 = phi i64 [ %indvars.iv.next553, %for.body344 ], [ 0, %for.body344.preheader ]
; CHECK: ret
if.end365: ; preds = %lor.lhs.false142, %lor.lhs.false138, %lor.lhs.false134, %entry
ret void
}
attributes #0 = { nounwind }

View File

@ -0,0 +1,15 @@
; RUN: opt < %s -loop-simplify
define void @foo(i1 %C) {
br i1 %C, label %T, label %F
T: ; preds = %0
br label %Loop
F: ; preds = %0
br label %Loop
Loop: ; preds = %L2, %Loop, %F, %T
%Val = phi i32 [ 0, %T ], [ 1, %F ], [ 2, %Loop ], [ 3, %L2 ] ; <i32> [#uses=0]
br i1 %C, label %Loop, label %L2
L2: ; preds = %Loop
br label %Loop
}

View File

@ -0,0 +1,35 @@
; RUN: opt -loop-simplify -S < %s | FileCheck %s
; LoopSimplify shouldn't split loop backedges that use indirectbr.
; CHECK: bb1: ; preds = %bb5, %bb
; CHECK-NEXT: indirectbr
; CHECK: bb5: ; preds = %bb1
; CHECK-NEXT: br label %bb1{{$}}
define void @foo(i8* %p) nounwind {
bb:
br label %bb1
bb1: ; preds = %bb5, %bb1, %bb
indirectbr i8* %p, [label %bb6, label %bb7, label %bb1, label %bb2, label %bb3, label %bb5, label %bb4]
bb2: ; preds = %bb1
ret void
bb3: ; preds = %bb1
ret void
bb4: ; preds = %bb1
ret void
bb5: ; preds = %bb1
br label %bb1
bb6: ; preds = %bb1
ret void
bb7: ; preds = %bb1
ret void
}

Some files were not shown because too many files have changed in this diff Show More