[TTI] getTypeBasedIntrinsicInstrCost - add basic handling for strided load/store...
[llvm-project.git] / llvm / test / Transforms / LICM / lnicm-sink.ll
blob96c812c6d8de565cfdd1ac0e131cfd0a6103f254
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:
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 ; }
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) {
26 entry:
27   br label %for.body
29 for.body:
30   %i.02 = phi i32 [ 0, %entry ], [ %inc6, %for.end ]
31   br label %for.body3
33 ; CHECK: for.body3:
34 ; LNICM: call i32 @abs(i32 %i.02)
35 ; LICM-NOT: call i32 @abs(i32 %i.02)
36 for.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
44 ; CHECK: for.end:
45 ; LICM: call i32 @abs(i32 %i.02)
46 ; LNICM-NOT: call i32 @abs(i32 %i.02)
47 for.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
57 ; CHECK: for.end7:
58 ; CHECK: call double @sin(double %x)
59 for.end7:
60   %t.0.lcssa = phi double [ %t.1.lcssa, %for.end ]
61   ret double %t.0.lcssa
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 ; }
80 define dso_local double @test2(double %x, ptr noalias %y) {
81 entry:
82   br label %for.body
84 for.body:
85   %i.02 = phi i32 [ 0, %entry ], [ %inc6, %for.end ]
86   br label %for.k
88 for.k:
89   %k = phi i64 [ 0, %for.body ], [ %inc.k, %for.end.k ]
90   br label %for.body3
92 ; CHECK: for.body3:
93 ; LNICM: call i32 @abs(i32 %i.02)
94 ; LICM-NOT: call i32 @abs(i32 %i.02)
95 for.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
103 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
110 ; CHECK: for.end:
111 ; LICM: call i32 @abs(i32 %i.02)
112 ; LNICM-NOT: call i32 @abs(i32 %i.02)
113 for.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
123 ; CHECK: for.end7:
124 ; CHECK: call double @sin(double %x)
125 for.end7:
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 }