• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -licm -S | FileCheck %s
2; RUN: opt -lcssa %s | opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,loop(licm)' -S | FileCheck %s
3
4@X = global i32 0		; <i32*> [#uses=1]
5
6declare void @foo()
7
8; This testcase tests for a problem where LICM hoists
9; potentially trapping instructions when they are not guaranteed to execute.
10define i32 @test1(i1 %c) {
11; CHECK-LABEL: @test1(
12	%A = load i32, i32* @X		; <i32> [#uses=2]
13	br label %Loop
14Loop:		; preds = %LoopTail, %0
15	call void @foo( )
16	br i1 %c, label %LoopTail, label %IfUnEqual
17
18IfUnEqual:		; preds = %Loop
19; CHECK: IfUnEqual:
20; CHECK-NEXT: sdiv i32 4, %A
21	%B1 = sdiv i32 4, %A		; <i32> [#uses=1]
22	br label %LoopTail
23
24LoopTail:		; preds = %IfUnEqual, %Loop
25	%B = phi i32 [ 0, %Loop ], [ %B1, %IfUnEqual ]		; <i32> [#uses=1]
26	br i1 %c, label %Loop, label %Out
27Out:		; preds = %LoopTail
28	%C = sub i32 %A, %B		; <i32> [#uses=1]
29	ret i32 %C
30}
31
32
33declare void @foo2(i32) nounwind
34
35
36;; It is ok and desirable to hoist this potentially trapping instruction.
37define i32 @test2(i1 %c) {
38; CHECK-LABEL: @test2(
39; CHECK-NEXT: load i32, i32* @X
40; CHECK-NEXT: %B = sdiv i32 4, %A
41  %A = load i32, i32* @X
42  br label %Loop
43
44Loop:
45  ;; Should have hoisted this div!
46  %B = sdiv i32 4, %A
47  br label %loop2
48
49loop2:
50  call void @foo2( i32 %B )
51  br i1 %c, label %Loop, label %Out
52
53Out:
54  %C = sub i32 %A, %B
55  ret i32 %C
56}
57
58
59; This loop invariant instruction should be constant folded, not hoisted.
60define i32 @test3(i1 %c) {
61; CHECK-LABEL: define i32 @test3(
62; CHECK: call void @foo2(i32 6)
63	%A = load i32, i32* @X		; <i32> [#uses=2]
64	br label %Loop
65Loop:
66	%B = add i32 4, 2		; <i32> [#uses=2]
67	call void @foo2( i32 %B )
68	br i1 %c, label %Loop, label %Out
69Out:		; preds = %Loop
70	%C = sub i32 %A, %B		; <i32> [#uses=1]
71	ret i32 %C
72}
73
74; CHECK-LABEL: @test4(
75; CHECK: call
76; CHECK: sdiv
77; CHECK: ret
78define i32 @test4(i32 %x, i32 %y) nounwind uwtable ssp {
79entry:
80  br label %for.body
81
82for.body:                                         ; preds = %entry, %for.body
83  %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
84  %n.01 = phi i32 [ 0, %entry ], [ %add, %for.body ]
85  call void @foo_may_call_exit(i32 0)
86  %div = sdiv i32 %x, %y
87  %add = add nsw i32 %n.01, %div
88  %inc = add nsw i32 %i.02, 1
89  %cmp = icmp slt i32 %inc, 10000
90  br i1 %cmp, label %for.body, label %for.end
91
92for.end:                                          ; preds = %for.body
93  %n.0.lcssa = phi i32 [ %add, %for.body ]
94  ret i32 %n.0.lcssa
95}
96
97declare void @foo_may_call_exit(i32)
98
99; PR14854
100; CHECK-LABEL: @test5(
101; CHECK: extractvalue
102; CHECK: br label %tailrecurse
103; CHECK: tailrecurse:
104; CHECK: ifend:
105; CHECK: insertvalue
106define { i32*, i32 } @test5(i32 %i, { i32*, i32 } %e) {
107entry:
108  br label %tailrecurse
109
110tailrecurse:                                      ; preds = %then, %entry
111  %i.tr = phi i32 [ %i, %entry ], [ %cmp2, %then ]
112  %out = extractvalue { i32*, i32 } %e, 1
113  %d = insertvalue { i32*, i32 } %e, i32* null, 0
114  %cmp1 = icmp sgt i32 %out, %i.tr
115  br i1 %cmp1, label %then, label %ifend
116
117then:                                             ; preds = %tailrecurse
118  call void @foo()
119  %cmp2 = add i32 %i.tr, 1
120  br label %tailrecurse
121
122ifend:                                            ; preds = %tailrecurse
123  ret { i32*, i32 } %d
124}
125