comparison llvm/test/Transforms/CodeGenPrepare/X86/sink-addrmode-inseltpoison.ll @ 252:1f2b6ac9f198 llvm-original

LLVM16-1
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 18 Aug 2023 09:04:13 +0900
parents 79ff65ed7e25
children
comparison
equal deleted inserted replaced
237:c80f45b162ad 252:1f2b6ac9f198
5 target triple = "x86_64-unknown-linux-gnu" 5 target triple = "x86_64-unknown-linux-gnu"
6 6
7 @x = external global [1 x [2 x <4 x float>]] 7 @x = external global [1 x [2 x <4 x float>]]
8 8
9 ; Can we sink single addressing mode computation to use? 9 ; Can we sink single addressing mode computation to use?
10 define void @test1(i1 %cond, i64* %base) { 10 define void @test1(i1 %cond, ptr %base) {
11 ; CHECK-LABEL: @test1 11 ; CHECK-LABEL: @test1
12 ; CHECK: getelementptr inbounds i8, {{.+}} 40 12 ; CHECK: getelementptr inbounds i8, {{.+}} 40
13 entry: 13 entry:
14 %addr = getelementptr inbounds i64, i64* %base, i64 5 14 %addr = getelementptr inbounds i64, ptr %base, i64 5
15 %casted = bitcast i64* %addr to i32* 15 br i1 %cond, label %if.then, label %fallthrough
16 br i1 %cond, label %if.then, label %fallthrough 16
17 17 if.then:
18 if.then: 18 %v = load i32, ptr %addr, align 4
19 %v = load i32, i32* %casted, align 4
20 br label %fallthrough 19 br label %fallthrough
21 20
22 fallthrough: 21 fallthrough:
23 ret void 22 ret void
24 } 23 }
25 24
26 declare void @foo(i32) 25 declare void @foo(i32)
27 26
28 ; Make sure sinking two copies of addressing mode into different blocks works 27 ; Make sure sinking two copies of addressing mode into different blocks works
29 define void @test2(i1 %cond, i64* %base) { 28 define void @test2(i1 %cond, ptr %base) {
30 ; CHECK-LABEL: @test2 29 ; CHECK-LABEL: @test2
31 entry: 30 entry:
32 %addr = getelementptr inbounds i64, i64* %base, i64 5 31 %addr = getelementptr inbounds i64, ptr %base, i64 5
33 %casted = bitcast i64* %addr to i32* 32 br i1 %cond, label %if.then, label %fallthrough
34 br i1 %cond, label %if.then, label %fallthrough 33
35 34 if.then:
36 if.then: 35 ; CHECK-LABEL: if.then:
37 ; CHECK-LABEL: if.then: 36 ; CHECK: getelementptr inbounds i8, {{.+}} 40
38 ; CHECK: getelementptr inbounds i8, {{.+}} 40 37 %v1 = load i32, ptr %addr, align 4
39 %v1 = load i32, i32* %casted, align 4
40 call void @foo(i32 %v1) 38 call void @foo(i32 %v1)
41 %cmp = icmp eq i32 %v1, 0 39 %cmp = icmp eq i32 %v1, 0
42 br i1 %cmp, label %next, label %fallthrough 40 br i1 %cmp, label %next, label %fallthrough
43 41
44 next: 42 next:
45 ; CHECK-LABEL: next: 43 ; CHECK-LABEL: next:
46 ; CHECK: getelementptr inbounds i8, {{.+}} 40 44 ; CHECK: getelementptr inbounds i8, {{.+}} 40
47 %v2 = load i32, i32* %casted, align 4 45 %v2 = load i32, ptr %addr, align 4
48 call void @foo(i32 %v2) 46 call void @foo(i32 %v2)
49 br label %fallthrough 47 br label %fallthrough
50 48
51 fallthrough: 49 fallthrough:
52 ret void 50 ret void
53 } 51 }
54 52
55 ; If we have two loads in the same block, only need one copy of addressing mode 53 ; If we have two loads in the same block, only need one copy of addressing mode
56 ; - instruction selection will duplicate if needed 54 ; - instruction selection will duplicate if needed
57 define void @test3(i1 %cond, i64* %base) { 55 define void @test3(i1 %cond, ptr %base) {
58 ; CHECK-LABEL: @test3 56 ; CHECK-LABEL: @test3
59 entry: 57 entry:
60 %addr = getelementptr inbounds i64, i64* %base, i64 5 58 %addr = getelementptr inbounds i64, ptr %base, i64 5
61 %casted = bitcast i64* %addr to i32* 59 br i1 %cond, label %if.then, label %fallthrough
62 br i1 %cond, label %if.then, label %fallthrough 60
63 61 if.then:
64 if.then: 62 ; CHECK-LABEL: if.then:
65 ; CHECK-LABEL: if.then: 63 ; CHECK: getelementptr inbounds i8, {{.+}} 40
66 ; CHECK: getelementptr inbounds i8, {{.+}} 40 64 %v1 = load i32, ptr %addr, align 4
67 %v1 = load i32, i32* %casted, align 4
68 call void @foo(i32 %v1) 65 call void @foo(i32 %v1)
69 ; CHECK-NOT: getelementptr inbounds i8, {{.+}} 40 66 ; CHECK-NOT: getelementptr inbounds i8, {{.+}} 40
70 %v2 = load i32, i32* %casted, align 4 67 %v2 = load i32, ptr %addr, align 4
71 call void @foo(i32 %v2) 68 call void @foo(i32 %v2)
72 br label %fallthrough 69 br label %fallthrough
73 70
74 fallthrough: 71 fallthrough:
75 ret void 72 ret void
76 } 73 }
77 74
78 ; Can we still sink addressing mode if there's a cold use of the 75 ; Can we still sink addressing mode if there's a cold use of the
79 ; address itself? 76 ; address itself?
80 define void @test4(i1 %cond, i64* %base) { 77 define void @test4(i1 %cond, ptr %base) {
81 ; CHECK-LABEL: @test4 78 ; CHECK-LABEL: @test4
82 entry: 79 entry:
83 %addr = getelementptr inbounds i64, i64* %base, i64 5 80 %addr = getelementptr inbounds i64, ptr %base, i64 5
84 %casted = bitcast i64* %addr to i32* 81 br i1 %cond, label %if.then, label %fallthrough
85 br i1 %cond, label %if.then, label %fallthrough 82
86 83 if.then:
87 if.then: 84 ; CHECK-LABEL: if.then:
88 ; CHECK-LABEL: if.then: 85 ; CHECK: getelementptr inbounds i8, {{.+}} 40
89 ; CHECK: getelementptr inbounds i8, {{.+}} 40 86 %v1 = load i32, ptr %addr, align 4
90 %v1 = load i32, i32* %casted, align 4
91 call void @foo(i32 %v1) 87 call void @foo(i32 %v1)
92 %cmp = icmp eq i32 %v1, 0 88 %cmp = icmp eq i32 %v1, 0
93 br i1 %cmp, label %rare.1, label %fallthrough 89 br i1 %cmp, label %rare.1, label %fallthrough
94 90
95 fallthrough: 91 fallthrough:
96 ret void 92 ret void
97 93
98 rare.1: 94 rare.1:
99 ; CHECK-LABEL: rare.1: 95 ; CHECK-LABEL: rare.1:
100 ; CHECK: getelementptr inbounds i8, {{.+}} 40 96 ; CHECK: getelementptr inbounds i8, {{.+}} 40
101 call void @slowpath(i32 %v1, i32* %casted) cold 97 call void @slowpath(i32 %v1, ptr %addr) cold
102 br label %fallthrough 98 br label %fallthrough
103 } 99 }
104 100
105 ; Negative test - don't want to duplicate addressing into hot path 101 ; Negative test - don't want to duplicate addressing into hot path
106 define void @test5(i1 %cond, i64* %base) { 102 define void @test5(i1 %cond, ptr %base) {
107 ; CHECK-LABEL: @test5 103 ; CHECK-LABEL: @test5
108 entry: 104 entry:
109 ; CHECK: %addr = getelementptr inbounds 105 ; CHECK: %addr = getelementptr inbounds
110 %addr = getelementptr inbounds i64, i64* %base, i64 5 106 %addr = getelementptr inbounds i64, ptr %base, i64 5
111 %casted = bitcast i64* %addr to i32*
112 br i1 %cond, label %if.then, label %fallthrough 107 br i1 %cond, label %if.then, label %fallthrough
113 108
114 if.then: 109 if.then:
115 ; CHECK-LABEL: if.then: 110 ; CHECK-LABEL: if.then:
116 ; CHECK-NOT: getelementptr inbounds i8, {{.+}} 40 111 ; CHECK-NOT: getelementptr inbounds i8, {{.+}} 40
117 %v1 = load i32, i32* %casted, align 4 112 %v1 = load i32, ptr %addr, align 4
118 call void @foo(i32 %v1) 113 call void @foo(i32 %v1)
119 %cmp = icmp eq i32 %v1, 0 114 %cmp = icmp eq i32 %v1, 0
120 br i1 %cmp, label %rare.1, label %fallthrough 115 br i1 %cmp, label %rare.1, label %fallthrough
121 116
122 fallthrough: 117 fallthrough:
123 ret void 118 ret void
124 119
125 rare.1: 120 rare.1:
126 call void @slowpath(i32 %v1, i32* %casted) ;; NOT COLD 121 call void @slowpath(i32 %v1, ptr %addr) ;; NOT COLD
127 br label %fallthrough 122 br label %fallthrough
128 } 123 }
129 124
130 ; Negative test - opt for size 125 ; Negative test - opt for size
131 define void @test6(i1 %cond, i64* %base) minsize { 126 define void @test6(i1 %cond, ptr %base) minsize {
132 ; CHECK-LABEL: @test6 127 ; CHECK-LABEL: @test6
133 entry: 128 entry:
134 ; CHECK: %addr = getelementptr 129 ; CHECK: %addr = getelementptr
135 %addr = getelementptr inbounds i64, i64* %base, i64 5 130 %addr = getelementptr inbounds i64, ptr %base, i64 5
136 %casted = bitcast i64* %addr to i32*
137 br i1 %cond, label %if.then, label %fallthrough 131 br i1 %cond, label %if.then, label %fallthrough
138 132
139 if.then: 133 if.then:
140 ; CHECK-LABEL: if.then: 134 ; CHECK-LABEL: if.then:
141 ; CHECK-NOT: getelementptr inbounds i8, {{.+}} 40 135 ; CHECK-NOT: getelementptr inbounds i8, {{.+}} 40
142 %v1 = load i32, i32* %casted, align 4 136 %v1 = load i32, ptr %addr, align 4
143 call void @foo(i32 %v1) 137 call void @foo(i32 %v1)
144 %cmp = icmp eq i32 %v1, 0 138 %cmp = icmp eq i32 %v1, 0
145 br i1 %cmp, label %rare.1, label %fallthrough 139 br i1 %cmp, label %rare.1, label %fallthrough
146 140
147 fallthrough: 141 fallthrough:
148 ret void 142 ret void
149 143
150 rare.1: 144 rare.1:
151 call void @slowpath(i32 %v1, i32* %casted) cold 145 call void @slowpath(i32 %v1, ptr %addr) cold
152 br label %fallthrough 146 br label %fallthrough
153 } 147 }
154 148
155 ; Negative test - opt for size 149 ; Negative test - opt for size
156 define void @test6_pgso(i1 %cond, i64* %base) !prof !14 { 150 define void @test6_pgso(i1 %cond, ptr %base) !prof !14 {
157 ; CHECK-LABEL: @test6 151 ; CHECK-LABEL: @test6
158 entry: 152 entry:
159 ; CHECK: %addr = getelementptr 153 ; CHECK: %addr = getelementptr
160 %addr = getelementptr inbounds i64, i64* %base, i64 5 154 %addr = getelementptr inbounds i64, ptr %base, i64 5
161 %casted = bitcast i64* %addr to i32*
162 br i1 %cond, label %if.then, label %fallthrough 155 br i1 %cond, label %if.then, label %fallthrough
163 156
164 if.then: 157 if.then:
165 ; CHECK-LABEL: if.then: 158 ; CHECK-LABEL: if.then:
166 ; CHECK-NOT: getelementptr inbounds i8, {{.+}} 40 159 ; CHECK-NOT: getelementptr inbounds i8, {{.+}} 40
167 %v1 = load i32, i32* %casted, align 4 160 %v1 = load i32, ptr %addr, align 4
168 call void @foo(i32 %v1) 161 call void @foo(i32 %v1)
169 %cmp = icmp eq i32 %v1, 0 162 %cmp = icmp eq i32 %v1, 0
170 br i1 %cmp, label %rare.1, label %fallthrough 163 br i1 %cmp, label %rare.1, label %fallthrough
171 164
172 fallthrough: 165 fallthrough:
173 ret void 166 ret void
174 167
175 rare.1: 168 rare.1:
176 call void @slowpath(i32 %v1, i32* %casted) cold 169 call void @slowpath(i32 %v1, ptr %addr) cold
177 br label %fallthrough 170 br label %fallthrough
178 } 171 }
179 172
180 ; Make sure sinking two copies of addressing mode into different blocks works 173 ; Make sure sinking two copies of addressing mode into different blocks works
181 ; when there are cold paths for each. 174 ; when there are cold paths for each.
182 define void @test7(i1 %cond, i64* %base) { 175 define void @test7(i1 %cond, ptr %base) {
183 ; CHECK-LABEL: @test7 176 ; CHECK-LABEL: @test7
184 entry: 177 entry:
185 %addr = getelementptr inbounds i64, i64* %base, i64 5 178 %addr = getelementptr inbounds i64, ptr %base, i64 5
186 %casted = bitcast i64* %addr to i32* 179 br i1 %cond, label %if.then, label %fallthrough
187 br i1 %cond, label %if.then, label %fallthrough 180
188 181 if.then:
189 if.then: 182 ; CHECK-LABEL: if.then:
190 ; CHECK-LABEL: if.then: 183 ; CHECK: getelementptr inbounds i8, {{.+}} 40
191 ; CHECK: getelementptr inbounds i8, {{.+}} 40 184 %v1 = load i32, ptr %addr, align 4
192 %v1 = load i32, i32* %casted, align 4
193 call void @foo(i32 %v1) 185 call void @foo(i32 %v1)
194 %cmp = icmp eq i32 %v1, 0 186 %cmp = icmp eq i32 %v1, 0
195 br i1 %cmp, label %rare.1, label %next 187 br i1 %cmp, label %rare.1, label %next
196 188
197 next: 189 next:
198 ; CHECK-LABEL: next: 190 ; CHECK-LABEL: next:
199 ; CHECK: getelementptr inbounds i8, {{.+}} 40 191 ; CHECK: getelementptr inbounds i8, {{.+}} 40
200 %v2 = load i32, i32* %casted, align 4 192 %v2 = load i32, ptr %addr, align 4
201 call void @foo(i32 %v2) 193 call void @foo(i32 %v2)
202 %cmp2 = icmp eq i32 %v2, 0 194 %cmp2 = icmp eq i32 %v2, 0
203 br i1 %cmp2, label %rare.1, label %fallthrough 195 br i1 %cmp2, label %rare.1, label %fallthrough
204 196
205 fallthrough: 197 fallthrough:
206 ret void 198 ret void
207 199
208 rare.1: 200 rare.1:
209 ; CHECK-LABEL: rare.1: 201 ; CHECK-LABEL: rare.1:
210 ; CHECK: getelementptr inbounds i8, {{.+}} 40 202 ; CHECK: getelementptr inbounds i8, {{.+}} 40
211 call void @slowpath(i32 %v1, i32* %casted) cold 203 call void @slowpath(i32 %v1, ptr %addr) cold
212 br label %next 204 br label %next
213 205
214 rare.2: 206 rare.2:
215 ; CHECK-LABEL: rare.2: 207 ; CHECK-LABEL: rare.2:
216 ; CHECK: getelementptr inbounds i8, {{.+}} 40 208 ; CHECK: getelementptr inbounds i8, {{.+}} 40
217 call void @slowpath(i32 %v2, i32* %casted) cold 209 call void @slowpath(i32 %v2, ptr %addr) cold
218 br label %fallthrough 210 br label %fallthrough
219 } 211 }
220 212
221 declare void @slowpath(i32, i32*) 213 declare void @slowpath(i32, ptr)
222 214
223 ; Make sure we don't end up in an infinite loop after we fail to sink. 215 ; Make sure we don't end up in an infinite loop after we fail to sink.
224 ; CHECK-LABEL: define void @test8 216 ; CHECK-LABEL: define void @test8
225 ; CHECK: %ptr = getelementptr i8, i8* %aFOO_load_ptr2int_2void, i32 undef 217 ; CHECK: %ptr = getelementptr i8, ptr %aFOO_load_ptr2int_2void, i32 undef
226 define void @test8() { 218 define void @test8() {
227 allocas: 219 allocas:
228 %aFOO_load = load float*, float** undef 220 %aFOO_load = load ptr, ptr undef
229 %aFOO_load_ptr2int = ptrtoint float* %aFOO_load to i64 221 %aFOO_load_ptr2int = ptrtoint ptr %aFOO_load to i64
230 %aFOO_load_ptr2int_broadcast_init = insertelement <4 x i64> poison, i64 %aFOO_load_ptr2int, i32 0 222 %aFOO_load_ptr2int_broadcast_init = insertelement <4 x i64> poison, i64 %aFOO_load_ptr2int, i32 0
231 %aFOO_load_ptr2int_2void = inttoptr i64 %aFOO_load_ptr2int to i8* 223 %aFOO_load_ptr2int_2void = inttoptr i64 %aFOO_load_ptr2int to ptr
232 %ptr = getelementptr i8, i8* %aFOO_load_ptr2int_2void, i32 undef 224 %ptr = getelementptr i8, ptr %aFOO_load_ptr2int_2void, i32 undef
233 br label %load.i145 225 br label %load.i145
234 226
235 load.i145: 227 load.i145:
236 %ptr.i143 = bitcast i8* %ptr to <4 x float>* 228 %valall.i144 = load <4 x float>, ptr %ptr, align 4
237 %valall.i144 = load <4 x float>, <4 x float>* %ptr.i143, align 4
238 %x_offset = getelementptr [1 x [2 x <4 x float>]], [1 x [2 x <4 x float>]]* @x, i32 0, i64 0
239 br label %pl_loop.i.i122 229 br label %pl_loop.i.i122
240 230
241 pl_loop.i.i122: 231 pl_loop.i.i122:
242 br label %pl_loop.i.i122 232 br label %pl_loop.i.i122
243 } 233 }
244 234
245 ; Make sure we can sink address computation even 235 ; Make sure we can sink address computation even
246 ; if there is a cycle in phi nodes. 236 ; if there is a cycle in phi nodes.
247 define void @test9(i1 %cond, i64* %base) { 237 define void @test9(i1 %cond, ptr %base) {
248 ; CHECK-LABEL: @test9 238 ; CHECK-LABEL: @test9
249 entry: 239 entry:
250 %addr = getelementptr inbounds i64, i64* %base, i64 5 240 %addr = getelementptr inbounds i64, ptr %base, i64 5
251 %casted = bitcast i64* %addr to i32*
252 br label %header 241 br label %header
253 242
254 header: 243 header:
255 %iv = phi i32 [0, %entry], [%iv.inc, %backedge] 244 %iv = phi i32 [0, %entry], [%iv.inc, %backedge]
256 %casted.loop = phi i32* [%casted, %entry], [%casted.merged, %backedge] 245 %casted.loop = phi ptr [%addr, %entry], [%casted.merged, %backedge]
257 br i1 %cond, label %if.then, label %backedge 246 br i1 %cond, label %if.then, label %backedge
258 247
259 if.then: 248 if.then:
260 call void @foo(i32 %iv) 249 call void @foo(i32 %iv)
261 %addr.1 = getelementptr inbounds i64, i64* %base, i64 5 250 %addr.1 = getelementptr inbounds i64, ptr %base, i64 5
262 %casted.1 = bitcast i64* %addr.1 to i32*
263 br label %backedge 251 br label %backedge
264 252
265 backedge: 253 backedge:
266 ; CHECK-LABEL: backedge: 254 ; CHECK-LABEL: backedge:
267 ; CHECK: getelementptr inbounds i8, {{.+}} 40 255 ; CHECK: getelementptr inbounds i8, {{.+}} 40
268 %casted.merged = phi i32* [%casted.loop, %header], [%casted.1, %if.then] 256 %casted.merged = phi ptr [%casted.loop, %header], [%addr.1, %if.then]
269 %v = load i32, i32* %casted.merged, align 4 257 %v = load i32, ptr %casted.merged, align 4
270 call void @foo(i32 %v) 258 call void @foo(i32 %v)
271 %iv.inc = add i32 %iv, 1 259 %iv.inc = add i32 %iv, 1
272 %cmp = icmp slt i32 %iv.inc, 1000 260 %cmp = icmp slt i32 %iv.inc, 1000
273 br i1 %cmp, label %header, label %exit 261 br i1 %cmp, label %header, label %exit
274 262
276 ret void 264 ret void
277 } 265 }
278 266
279 ; Make sure we can eliminate a select when both arguments perform equivalent 267 ; Make sure we can eliminate a select when both arguments perform equivalent
280 ; address computation. 268 ; address computation.
281 define void @test10(i1 %cond, i64* %base) { 269 define void @test10(i1 %cond, ptr %base) {
282 ; CHECK-LABEL: @test10 270 ; CHECK-LABEL: @test10
283 ; CHECK: getelementptr inbounds i8, {{.+}} 40 271 ; CHECK: getelementptr inbounds i8, {{.+}} 40
284 ; CHECK-NOT: select 272 ; CHECK-NOT: select
285 entry: 273 entry:
286 %gep1 = getelementptr inbounds i64, i64* %base, i64 5 274 %gep1 = getelementptr inbounds i64, ptr %base, i64 5
287 %gep1.casted = bitcast i64* %gep1 to i32* 275 %gep2 = getelementptr inbounds i32, ptr %base, i64 10
288 %base.casted = bitcast i64* %base to i32* 276 %casted.merged = select i1 %cond, ptr %gep1, ptr %gep2
289 %gep2 = getelementptr inbounds i32, i32* %base.casted, i64 10 277 %v = load i32, ptr %casted.merged, align 4
290 %casted.merged = select i1 %cond, i32* %gep1.casted, i32* %gep2
291 %v = load i32, i32* %casted.merged, align 4
292 call void @foo(i32 %v) 278 call void @foo(i32 %v)
293 ret void 279 ret void
294 } 280 }
295 281
296 ; Found by fuzzer, getSExtValue of > 64 bit constant 282 ; Found by fuzzer, getSExtValue of > 64 bit constant
297 define void @i96_mul(i1* %base, i96 %offset) { 283 define void @i96_mul(ptr %base, i96 %offset) {
298 BB: 284 BB:
299 ;; RHS = 0x7FFFFFFFFFFFFFFFFFFFFFFF 285 ;; RHS = 0x7FFFFFFFFFFFFFFFFFFFFFFF
300 %B84 = mul i96 %offset, 39614081257132168796771975167 286 %B84 = mul i96 %offset, 39614081257132168796771975167
301 %G23 = getelementptr i1, i1* %base, i96 %B84 287 %G23 = getelementptr i1, ptr %base, i96 %B84
302 store i1 false, i1* %G23 288 store i1 false, ptr %G23
303 ret void 289 ret void
304 } 290 }
305 291
306 !llvm.module.flags = !{!0} 292 !llvm.module.flags = !{!0}
307 !0 = !{i32 1, !"ProfileSummary", !1} 293 !0 = !{i32 1, !"ProfileSummary", !1}