xref: /llvm-project/llvm/test/Transforms/LICM/lnicm-sink.ll (revision 07253bc8c0a1f7f502fc5bb94f4205752c0d22e4)
1; RUN: opt -passes='loop-mssa(licm)' -S %s | FileCheck %s --check-prefixes CHECK,LICM
2; RUN: opt -passes='loop-mssa(lnicm)' -S %s | FileCheck %s --check-prefixes CHECK,LNICM
3
4; This test represents the following function:
5;
6; double sin(double);
7; int abs(int);
8; double test(double x, int y[10]) {
9;   double t = 0; int s = 0;
10;   for (int i = 0; i < 10; i++) {
11;     for (int j = 0; j < 10; j++) {
12;       t = sin(x);
13;       s = abs(i);
14;     }
15;     y[i] = s;
16;   }
17;   return t;
18; }
19;
20; We only want to sink the call of sin out of the loop nest.
21; LICM also sinks the call of abs out of j-loop, but LNICM doesn't do so
22; to try to make a perfect loop nest. (though y[i] = s; still prevents the
23; loop nest from being a perfect loop nest in this test case)
24
25define dso_local double @test(double %x, ptr noalias %y) {
26entry:
27  br label %for.body
28
29for.body:
30  %i.02 = phi i32 [ 0, %entry ], [ %inc6, %for.end ]
31  br label %for.body3
32
33; CHECK: for.body3:
34; LNICM: call i32 @abs(i32 %i.02)
35; LICM-NOT: call i32 @abs(i32 %i.02)
36for.body3:
37  %j.01 = phi i32 [ 0, %for.body ], [ %inc, %for.body3 ]
38  %call = call double @sin(double %x)
39  %call4 = call i32 @abs(i32 %i.02)
40  %inc = add nsw i32 %j.01, 1
41  %cmp2 = icmp slt i32 %inc, 10
42  br i1 %cmp2, label %for.body3, label %for.end
43
44; CHECK: for.end:
45; LICM: call i32 @abs(i32 %i.02)
46; LNICM-NOT: call i32 @abs(i32 %i.02)
47for.end:
48  %s.1.lcssa = phi i32 [ %call4, %for.body3 ]
49  %t.1.lcssa = phi double [ %call, %for.body3 ]
50  %idxprom = sext i32 %i.02 to i64
51  %arrayidx = getelementptr inbounds i32, ptr %y, i64 %idxprom
52  store i32 %s.1.lcssa, ptr %arrayidx, align 4
53  %inc6 = add nsw i32 %i.02, 1
54  %cmp = icmp slt i32 %inc6, 10
55  br i1 %cmp, label %for.body, label %for.end7
56
57; CHECK: for.end7:
58; CHECK: call double @sin(double %x)
59for.end7:
60  %t.0.lcssa = phi double [ %t.1.lcssa, %for.end ]
61  ret double %t.0.lcssa
62}
63
64; double sin(double);
65; int abs(int);
66; double test(double x, int y[10]) {
67;   double t = 0; int s = 0;
68;   for (int i = 0; i < 10; i++) {
69;     for (int k = 0; k < 10; k++) {
70;       for (int j = 0; j < 10; j++) {
71;         t = sin(x);
72;         s = abs(i);
73;       }
74;     }
75;     y[i] = s;
76;   }
77;   return t;
78; }
79;
80define dso_local double @test2(double %x, ptr noalias %y) {
81entry:
82  br label %for.body
83
84for.body:
85  %i.02 = phi i32 [ 0, %entry ], [ %inc6, %for.end ]
86  br label %for.k
87
88for.k:
89  %k = phi i64 [ 0, %for.body ], [ %inc.k, %for.end.k ]
90  br label %for.body3
91
92; CHECK: for.body3:
93; LNICM: call i32 @abs(i32 %i.02)
94; LICM-NOT: call i32 @abs(i32 %i.02)
95for.body3:
96  %j.01 = phi i32 [ 0, %for.k ], [ %inc, %for.body3 ]
97  %call = call double @sin(double %x)
98  %call4 = call i32 @abs(i32 %i.02)
99  %inc = add nsw i32 %j.01, 1
100  %cmp2 = icmp slt i32 %inc, 10
101  br i1 %cmp2, label %for.body3, label %for.end.k
102
103for.end.k:
104  %s.lcssa.k = phi i32 [ %call4, %for.body3 ]
105  %t.lcssa.k = phi double [ %call, %for.body3 ]
106  %inc.k = add nsw i64 %k, 1
107  %cmp.k = icmp slt i64 %inc.k, 10
108  br i1 %cmp.k, label %for.k, label %for.end
109
110; CHECK: for.end:
111; LICM: call i32 @abs(i32 %i.02)
112; LNICM-NOT: call i32 @abs(i32 %i.02)
113for.end:
114  %s.1.lcssa = phi i32 [ %s.lcssa.k, %for.end.k ]
115  %t.1.lcssa = phi double [ %t.lcssa.k, %for.end.k ]
116  %idxprom = sext i32 %i.02 to i64
117  %arrayidx = getelementptr inbounds i32, ptr %y, i64 %idxprom
118  store i32 %s.1.lcssa, ptr %arrayidx, align 4
119  %inc6 = add nsw i32 %i.02, 1
120  %cmp = icmp slt i32 %inc6, 10
121  br i1 %cmp, label %for.body, label %for.end7
122
123; CHECK: for.end7:
124; CHECK: call double @sin(double %x)
125for.end7:
126  %t.0.lcssa = phi double [ %t.1.lcssa, %for.end ]
127  ret double %t.0.lcssa
128}
129
130declare dso_local double @sin(double) #0
131
132declare dso_local i32 @abs(i32) #0
133
134attributes #0 = { nounwind readnone willreturn }
135