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
4 ; This test represents the following function:
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++) {
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)
25 define dso_local double @test(double %x, ptr noalias %y) {
30 %i.02 = phi i32 [ 0, %entry ], [ %inc6, %for.end ]
34 ; LNICM: call i32 @abs(i32 %i.02)
35 ; LICM-NOT: call i32 @abs(i32 %i.02)
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
45 ; LICM: call i32 @abs(i32 %i.02)
46 ; LNICM-NOT: call i32 @abs(i32 %i.02)
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
58 ; CHECK: call double @sin(double %x)
60 %t.0.lcssa = phi double [ %t.1.lcssa, %for.end ]
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++) {
80 define dso_local double @test2(double %x, ptr noalias %y) {
85 %i.02 = phi i32 [ 0, %entry ], [ %inc6, %for.end ]
89 %k = phi i64 [ 0, %for.body ], [ %inc.k, %for.end.k ]
93 ; LNICM: call i32 @abs(i32 %i.02)
94 ; LICM-NOT: call i32 @abs(i32 %i.02)
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
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
111 ; LICM: call i32 @abs(i32 %i.02)
112 ; LNICM-NOT: call i32 @abs(i32 %i.02)
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
124 ; CHECK: call double @sin(double %x)
126 %t.0.lcssa = phi double [ %t.1.lcssa, %for.end ]
127 ret double %t.0.lcssa
130 declare dso_local double @sin(double) #0
132 declare dso_local i32 @abs(i32) #0
134 attributes #0 = { nounwind readnone willreturn }