[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Transforms / CorrelatedValuePropagation / ashr.ll
blobdcc90d548d698e8f18db5cf0edf2b9f1fccd20d5
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
4 define void @test1(i32 %n) {
5 ; CHECK-LABEL: define void @test1(
6 ; CHECK-SAME: i32 [[N:%.*]]) {
7 ; CHECK-NEXT:  [[ENTRY:.*]]:
8 ; CHECK-NEXT:    br label %[[FOR_COND:.*]]
9 ; CHECK:       [[FOR_COND]]:
10 ; CHECK-NEXT:    [[A:%.*]] = phi i32 [ [[N]], %[[ENTRY]] ], [ [[SHR:%.*]], %[[FOR_BODY:.*]] ]
11 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 1
12 ; CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_END:.*]]
13 ; CHECK:       [[FOR_BODY]]:
14 ; CHECK-NEXT:    [[SHR]] = lshr i32 [[A]], 5
15 ; CHECK-NEXT:    br label %[[FOR_COND]]
16 ; CHECK:       [[FOR_END]]:
17 ; CHECK-NEXT:    ret void
19 entry:
20   br label %for.cond
22 for.cond:                                         ; preds = %for.body, %entry
23   %a = phi i32 [ %n, %entry ], [ %shr, %for.body ]
24   %cmp = icmp sgt i32 %a, 1
25   br i1 %cmp, label %for.body, label %for.end
27 for.body:                                         ; preds = %for.cond
28   %shr = ashr i32 %a, 5
29   br label %for.cond
31 for.end:                                          ; preds = %for.cond
32   ret void
35 ;; Negative test to show transform doesn't happen unless n > 0.
36 define void @test2(i32 %n) {
37 ; CHECK-LABEL: define void @test2(
38 ; CHECK-SAME: i32 [[N:%.*]]) {
39 ; CHECK-NEXT:  [[ENTRY:.*]]:
40 ; CHECK-NEXT:    br label %[[FOR_COND:.*]]
41 ; CHECK:       [[FOR_COND]]:
42 ; CHECK-NEXT:    [[A:%.*]] = phi i32 [ [[N]], %[[ENTRY]] ], [ [[SHR:%.*]], %[[FOR_BODY:.*]] ]
43 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], -2
44 ; CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_END:.*]]
45 ; CHECK:       [[FOR_BODY]]:
46 ; CHECK-NEXT:    [[SHR]] = ashr i32 [[A]], 2
47 ; CHECK-NEXT:    br label %[[FOR_COND]]
48 ; CHECK:       [[FOR_END]]:
49 ; CHECK-NEXT:    ret void
51 entry:
52   br label %for.cond
54 for.cond:                                         ; preds = %for.body, %entry
55   %a = phi i32 [ %n, %entry ], [ %shr, %for.body ]
56   %cmp = icmp sgt i32 %a, -2
57   br i1 %cmp, label %for.body, label %for.end
59 for.body:                                         ; preds = %for.cond
60   %shr = ashr i32 %a, 2
61   br label %for.cond
63 for.end:                                          ; preds = %for.cond
64   ret void
67 ;; Non looping test case.
68 define void @test3(i32 %n) {
69 ; CHECK-LABEL: define void @test3(
70 ; CHECK-SAME: i32 [[N:%.*]]) {
71 ; CHECK-NEXT:  [[ENTRY:.*:]]
72 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
73 ; CHECK-NEXT:    br i1 [[CMP]], label %[[BB:.*]], label %[[EXIT:.*]]
74 ; CHECK:       [[BB]]:
75 ; CHECK-NEXT:    [[SHR:%.*]] = lshr exact i32 [[N]], 4
76 ; CHECK-NEXT:    br label %[[EXIT]]
77 ; CHECK:       [[EXIT]]:
78 ; CHECK-NEXT:    ret void
80 entry:
81   %cmp = icmp sgt i32 %n, 0
82   br i1 %cmp, label %bb, label %exit
84 bb:
85   %shr = ashr exact i32 %n, 4
86   br label %exit
88 exit:
89   ret void
92 ; looping case where loop has exactly one block
93 ; at the point of ashr, we know that the operand is always greater than 0,
94 ; because of the guard before it, so we can transform it to lshr.
95 declare void @llvm.experimental.guard(i1,...)
96 define void @test4(i32 %n) {
97 ; CHECK-LABEL: define void @test4(
98 ; CHECK-SAME: i32 [[N:%.*]]) {
99 ; CHECK-NEXT:  [[ENTRY:.*]]:
100 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
101 ; CHECK-NEXT:    br i1 [[CMP]], label %[[LOOP:.*]], label %[[EXIT:.*]]
102 ; CHECK:       [[LOOP]]:
103 ; CHECK-NEXT:    [[A:%.*]] = phi i32 [ [[N]], %[[ENTRY]] ], [ [[SHR:%.*]], %[[LOOP]] ]
104 ; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i32 [[A]], 2
105 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND]]) [ "deopt"() ]
106 ; CHECK-NEXT:    [[SHR]] = lshr i32 [[A]], 1
107 ; CHECK-NEXT:    br i1 [[COND]], label %[[LOOP]], label %[[EXIT]]
108 ; CHECK:       [[EXIT]]:
109 ; CHECK-NEXT:    ret void
111 entry:
112   %cmp = icmp sgt i32 %n, 0
113   br i1 %cmp, label %loop, label %exit
115 loop:
116   %a = phi i32 [ %n, %entry ], [ %shr, %loop ]
117   %cond = icmp sgt i32 %a, 2
118   call void(i1,...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]
119   %shr = ashr i32 %a, 1
120   br i1 %cond, label %loop, label %exit
122 exit:
123   ret void
126 ; same test as above with assume instead of guard.
127 declare void @llvm.assume(i1)
128 define void @test5(i32 %n) {
129 ; CHECK-LABEL: define void @test5(
130 ; CHECK-SAME: i32 [[N:%.*]]) {
131 ; CHECK-NEXT:  [[ENTRY:.*]]:
132 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
133 ; CHECK-NEXT:    br i1 [[CMP]], label %[[LOOP:.*]], label %[[EXIT:.*]]
134 ; CHECK:       [[LOOP]]:
135 ; CHECK-NEXT:    [[A:%.*]] = phi i32 [ [[N]], %[[ENTRY]] ], [ [[SHR:%.*]], %[[LOOP]] ]
136 ; CHECK-NEXT:    [[COND:%.*]] = icmp samesign ugt i32 [[A]], 4
137 ; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])
138 ; CHECK-NEXT:    [[SHR]] = lshr i32 [[A]], 1
139 ; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp samesign ugt i32 [[SHR]], 8
140 ; CHECK-NEXT:    br i1 [[LOOPCOND]], label %[[LOOP]], label %[[EXIT]]
141 ; CHECK:       [[EXIT]]:
142 ; CHECK-NEXT:    ret void
144 entry:
145   %cmp = icmp sgt i32 %n, 0
146   br i1 %cmp, label %loop, label %exit
148 loop:
149   %a = phi i32 [ %n, %entry ], [ %shr, %loop ]
150   %cond = icmp sgt i32 %a, 4
151   call void @llvm.assume(i1 %cond)
152   %shr = ashr i32 %a, 1
153   %loopcond = icmp sgt i32 %shr, 8
154   br i1 %loopcond, label %loop, label %exit
156 exit:
157   ret void
160 ; check that ashr of -1 or 0 is optimized away
161 define i32 @test6(i32 %f, i32 %g) {
162 ; CHECK-LABEL: define range(i32 -1, 1) i32 @test6(
163 ; CHECK-SAME: i32 [[F:%.*]], i32 [[G:%.*]]) {
164 ; CHECK-NEXT:  [[ENTRY:.*:]]
165 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[F]], 1
166 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[TMP0]], 2
167 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[TMP1]])
168 ; CHECK-NEXT:    ret i32 [[F]]
170 entry:
171   %0 = add i32 %f, 1
172   %1 = icmp ult i32 %0, 2
173   tail call void @llvm.assume(i1 %1)
174   %shr = ashr i32 %f, %g
175   ret i32 %shr
178 ; same test as above with different numbers
179 define i32 @test7(i32 %f, i32 %g) {
180 ; CHECK-LABEL: define range(i32 -1, 1) i32 @test7(
181 ; CHECK-SAME: i32 [[F:%.*]], i32 [[G:%.*]]) {
182 ; CHECK-NEXT:  [[ENTRY:.*:]]
183 ; CHECK-NEXT:    [[TMP0:%.*]] = and i32 [[F]], -2
184 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 6
185 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[TMP1]])
186 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[F]], -7
187 ; CHECK-NEXT:    ret i32 [[SUB]]
189 entry:
190   %0 = and i32 %f, -2
191   %1 = icmp eq i32 %0, 6
192   tail call void @llvm.assume(i1 %1)
193   %sub = add nsw i32 %f, -7
194   %shr = ashr i32 %sub, %g
195   ret i32 %shr
198 ; check that ashr of -2 or 1 is not optimized away
199 define i32 @test8(i32 %f, i32 %g, i1 %s) {
200 ; CHECK-LABEL: define range(i32 -2, 2) i32 @test8(
201 ; CHECK-SAME: i32 [[F:%.*]], i32 [[G:%.*]], i1 [[S:%.*]]) {
202 ; CHECK-NEXT:  [[ENTRY:.*:]]
203 ; CHECK-NEXT:    [[TMP0:%.*]] = ashr i32 -2, [[F]]
204 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 1, [[G]]
205 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[S]], i32 [[TMP0]], i32 [[TMP1]]
206 ; CHECK-NEXT:    ret i32 [[TMP2]]
208 entry:
209   %0 = ashr i32 -2, %f
210   %1 = ashr i32 1, %g
211   %2 = select i1 %s, i32 %0, i32 %1
212   ret i32 %2
215 define i32 @may_including_undef(i1 %c.1, i1 %c.2) {
216 ; CHECK-LABEL: define range(i32 -1073741824, 1073741824) i32 @may_including_undef(
217 ; CHECK-SAME: i1 [[C_1:%.*]], i1 [[C_2:%.*]]) {
218 ; CHECK-NEXT:    br i1 [[C_1]], label %[[TRUE_1:.*]], label %[[FALSE:.*]]
219 ; CHECK:       [[TRUE_1]]:
220 ; CHECK-NEXT:    br i1 [[C_2]], label %[[TRUE_2:.*]], label %[[EXIT:.*]]
221 ; CHECK:       [[TRUE_2]]:
222 ; CHECK-NEXT:    br label %[[EXIT]]
223 ; CHECK:       [[FALSE]]:
224 ; CHECK-NEXT:    br label %[[EXIT]]
225 ; CHECK:       [[EXIT]]:
226 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 2, %[[TRUE_1]] ], [ 4, %[[TRUE_2]] ], [ undef, %[[FALSE]] ]
227 ; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[P]], 1
228 ; CHECK-NEXT:    ret i32 [[R]]
230   br i1 %c.1, label %true.1, label %false
232 true.1:
233   br i1 %c.2, label %true.2, label %exit
235 true.2:
236   br label %exit
238 false:
239   br label %exit
241 exit:
242   %p = phi i32 [ 2, %true.1 ], [ 4, %true.2], [ undef, %false ]
243   %r = ashr i32 %p, 1
244   ret i32 %r