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