1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 target datalayout = "p1:64:64:64:32"
6 declare ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1), i32)
7 declare ptr @llvm.ptrmask.p0.i64(ptr, i64)
8 declare <2 x ptr addrspace(1) > @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1) >, <2 x i32>)
9 declare <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr>, <2 x i64>)
11 define ptr @ptrmask_combine_consecutive_preserve_attrs(ptr %p0, i64 %m1) {
12 ; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs
13 ; CHECK-SAME: (ptr [[P0:%.*]], i64 [[M1:%.*]]) {
14 ; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[M1]], 224
15 ; CHECK-NEXT: [[R:%.*]] = call noalias align 32 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[TMP1]])
16 ; CHECK-NEXT: ret ptr [[R]]
18 %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 224)
19 %r = call noalias ptr @llvm.ptrmask.p0.i64(ptr %pm0, i64 %m1)
23 define <2 x ptr> @ptrmask_combine_consecutive_preserve_attrs_vecs(<2 x ptr> %p0, <2 x i64> %m1) {
24 ; CHECK-LABEL: define <2 x ptr> @ptrmask_combine_consecutive_preserve_attrs_vecs
25 ; CHECK-SAME: (<2 x ptr> [[P0:%.*]], <2 x i64> [[M1:%.*]]) {
26 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i64> [[M1]], <i64 12345, i64 12345>
27 ; CHECK-NEXT: [[R:%.*]] = call align 128 <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> [[P0]], <2 x i64> [[TMP1]])
28 ; CHECK-NEXT: ret <2 x ptr> [[R]]
30 %pm0 = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %p0, <2 x i64> <i64 12345, i64 12345>)
31 %r = call align 128 <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %pm0, <2 x i64> %m1)
35 define ptr @ptrmask_combine_consecutive_preserve_attrs_fail(ptr %p0, i64 %m0) {
36 ; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs_fail
37 ; CHECK-SAME: (ptr [[P0:%.*]], i64 [[M0:%.*]]) {
38 ; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[M0]], 193
39 ; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[TMP1]])
40 ; CHECK-NEXT: ret ptr [[R]]
42 %pm0 = call noalias ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)
43 %r = call ptr @llvm.ptrmask.p0.i64(ptr %pm0, i64 193)
47 define ptr @ptrmask_combine_consecutive_preserve_attrs_todo0(ptr %p0) {
48 ; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs_todo0
49 ; CHECK-SAME: (ptr [[P0:%.*]]) {
50 ; CHECK-NEXT: [[PM0:%.*]] = call noalias align 32 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 224)
51 ; CHECK-NEXT: ret ptr [[PM0]]
53 %pm0 = call noalias ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 224)
54 %r = call ptr @llvm.ptrmask.p0.i64(ptr %pm0, i64 224)
58 define ptr @ptrmask_combine_consecutive_preserve_attrs_todo1(ptr %p0) {
59 ; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs_todo1
60 ; CHECK-SAME: (ptr [[P0:%.*]]) {
61 ; CHECK-NEXT: [[PM0:%.*]] = call align 32 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 224)
62 ; CHECK-NEXT: ret ptr [[PM0]]
64 %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 224)
65 %r = call noalias ptr @llvm.ptrmask.p0.i64(ptr %pm0, i64 224)
69 define ptr addrspace(1) @ptrmask_combine_consecutive_preserve_attrs_todo2(ptr addrspace(1) %p0) {
70 ; CHECK-LABEL: define ptr addrspace(1) @ptrmask_combine_consecutive_preserve_attrs_todo2
71 ; CHECK-SAME: (ptr addrspace(1) [[P0:%.*]]) {
72 ; CHECK-NEXT: [[PM0:%.*]] = call noalias align 32 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P0]], i32 224)
73 ; CHECK-NEXT: ret ptr addrspace(1) [[PM0]]
75 %pm0 = call noalias ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p0, i32 224)
76 %r = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %pm0, i32 224)
77 ret ptr addrspace(1) %r
80 define ptr @ptrmask_combine_add_nonnull(ptr %p) {
81 ; CHECK-LABEL: define ptr @ptrmask_combine_add_nonnull
82 ; CHECK-SAME: (ptr [[P:%.*]]) {
83 ; CHECK-NEXT: [[PM0:%.*]] = call align 4 ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -60)
84 ; CHECK-NEXT: [[PGEP1:%.*]] = getelementptr i8, ptr [[PM0]], i64 32
85 ; CHECK-NEXT: [[R:%.*]] = call nonnull align 32 ptr @llvm.ptrmask.p0.i64(ptr [[PGEP1]], i64 -32)
86 ; CHECK-NEXT: ret ptr [[R]]
88 %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -60)
89 %pgep = getelementptr i8, ptr %pm0, i64 33
90 %r = call ptr @llvm.ptrmask.p0.i64(ptr %pgep, i64 -16)
94 define ptr @ptrmask_combine_add_alignment(ptr %p) {
95 ; CHECK-LABEL: define ptr @ptrmask_combine_add_alignment
96 ; CHECK-SAME: (ptr [[P:%.*]]) {
97 ; CHECK-NEXT: [[R:%.*]] = call align 64 ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -64)
98 ; CHECK-NEXT: ret ptr [[R]]
100 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -64)
104 define ptr addrspace(1) @ptrmask_combine_add_alignment2(ptr addrspace(1) align 32 %p) {
105 ; CHECK-LABEL: define ptr addrspace(1) @ptrmask_combine_add_alignment2
106 ; CHECK-SAME: (ptr addrspace(1) align 32 [[P:%.*]]) {
107 ; CHECK-NEXT: [[R:%.*]] = call align 64 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P]], i32 -64)
108 ; CHECK-NEXT: ret ptr addrspace(1) [[R]]
110 %r = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p, i32 -64)
111 ret ptr addrspace(1) %r
114 define <2 x ptr> @ptrmask_combine_add_alignment_vec(<2 x ptr> %p) {
115 ; CHECK-LABEL: define <2 x ptr> @ptrmask_combine_add_alignment_vec
116 ; CHECK-SAME: (<2 x ptr> [[P:%.*]]) {
117 ; CHECK-NEXT: [[R:%.*]] = call align 32 <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> [[P]], <2 x i64> <i64 -96, i64 -96>)
118 ; CHECK-NEXT: ret <2 x ptr> [[R]]
120 %r = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %p, <2 x i64> <i64 -96, i64 -96>)
124 define ptr addrspace(1) @ptrmask_combine_improve_alignment(ptr addrspace(1) %p) {
125 ; CHECK-LABEL: define ptr addrspace(1) @ptrmask_combine_improve_alignment
126 ; CHECK-SAME: (ptr addrspace(1) [[P:%.*]]) {
127 ; CHECK-NEXT: [[R:%.*]] = call align 64 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P]], i32 -64)
128 ; CHECK-NEXT: ret ptr addrspace(1) [[R]]
130 %r = call align 32 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p, i32 -64)
131 ret ptr addrspace(1) %r
134 define <2 x ptr addrspace(1) > @ptrmask_combine_improve_alignment_vec(<2 x ptr addrspace(1) > %p) {
135 ; CHECK-LABEL: define <2 x ptr addrspace(1)> @ptrmask_combine_improve_alignment_vec
136 ; CHECK-SAME: (<2 x ptr addrspace(1)> [[P:%.*]]) {
137 ; CHECK-NEXT: [[R:%.*]] = call align 64 <2 x ptr addrspace(1)> @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1)> [[P]], <2 x i32> <i32 -64, i32 -128>)
138 ; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[R]]
140 %r = call align 32 <2 x ptr addrspace(1) > @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1) > %p, <2 x i32> <i32 -64, i32 -128>)
141 ret <2 x ptr addrspace(1) > %r
144 define ptr addrspace(1) @ptrmask_combine_improve_alignment_fail(ptr addrspace(1) %p) {
145 ; CHECK-LABEL: define ptr addrspace(1) @ptrmask_combine_improve_alignment_fail
146 ; CHECK-SAME: (ptr addrspace(1) [[P:%.*]]) {
147 ; CHECK-NEXT: [[R:%.*]] = call align 128 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P]], i32 -64)
148 ; CHECK-NEXT: ret ptr addrspace(1) [[R]]
150 %r = call align 128 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p, i32 -64)
151 ret ptr addrspace(1) %r
154 define i64 @ptrtoint_of_ptrmask(ptr %p, i64 %m) {
155 ; CHECK-LABEL: define i64 @ptrtoint_of_ptrmask
156 ; CHECK-SAME: (ptr [[P:%.*]], i64 [[M:%.*]]) {
157 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P]] to i64
158 ; CHECK-NEXT: [[R:%.*]] = and i64 [[TMP1]], [[M]]
159 ; CHECK-NEXT: ret i64 [[R]]
161 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m)
162 %r = ptrtoint ptr %pm to i64
166 ; This succeeds because (ptrtoint i32) gets folded to (trunc i32 (ptrtoint i64))
167 define i32 @ptrtoint_of_ptrmask2(ptr %p, i64 %m) {
168 ; CHECK-LABEL: define i32 @ptrtoint_of_ptrmask2
169 ; CHECK-SAME: (ptr [[P:%.*]], i64 [[M:%.*]]) {
170 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P]] to i64
171 ; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], [[M]]
172 ; CHECK-NEXT: [[R:%.*]] = trunc i64 [[TMP2]] to i32
173 ; CHECK-NEXT: ret i32 [[R]]
175 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m)
176 %r = ptrtoint ptr %pm to i32
180 define <2 x i64> @ptrtoint_of_ptrmask_vec(<2 x ptr> %p, <2 x i64> %m) {
181 ; CHECK-LABEL: define <2 x i64> @ptrtoint_of_ptrmask_vec
182 ; CHECK-SAME: (<2 x ptr> [[P:%.*]], <2 x i64> [[M:%.*]]) {
183 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint <2 x ptr> [[P]] to <2 x i64>
184 ; CHECK-NEXT: [[R:%.*]] = and <2 x i64> [[TMP1]], [[M]]
185 ; CHECK-NEXT: ret <2 x i64> [[R]]
187 %pm = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %p, <2 x i64> %m)
188 %r = ptrtoint <2 x ptr> %pm to <2 x i64>
192 define <2 x i32> @ptrtoint_of_ptrmask_vec2(<2 x ptr> %p, <2 x i64> %m) {
193 ; CHECK-LABEL: define <2 x i32> @ptrtoint_of_ptrmask_vec2
194 ; CHECK-SAME: (<2 x ptr> [[P:%.*]], <2 x i64> [[M:%.*]]) {
195 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint <2 x ptr> [[P]] to <2 x i64>
196 ; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i64> [[TMP1]], [[M]]
197 ; CHECK-NEXT: [[R:%.*]] = trunc <2 x i64> [[TMP2]] to <2 x i32>
198 ; CHECK-NEXT: ret <2 x i32> [[R]]
200 %pm = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %p, <2 x i64> %m)
201 %r = ptrtoint <2 x ptr> %pm to <2 x i32>
205 define i64 @ptrtoint_of_ptrmask_fail(ptr addrspace(1) %p, i32 %m) {
206 ; CHECK-LABEL: define i64 @ptrtoint_of_ptrmask_fail
207 ; CHECK-SAME: (ptr addrspace(1) [[P:%.*]], i32 [[M:%.*]]) {
208 ; CHECK-NEXT: [[PM:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P]], i32 [[M]])
209 ; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr addrspace(1) [[PM]] to i64
210 ; CHECK-NEXT: ret i64 [[R]]
212 %pm = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p, i32 %m)
213 %r = ptrtoint ptr addrspace(1) %pm to i64
217 define <2 x i32> @ptrtoint_of_ptrmask_vec_fail(<2 x ptr addrspace(1) > %p, <2 x i32> %m) {
218 ; CHECK-LABEL: define <2 x i32> @ptrtoint_of_ptrmask_vec_fail
219 ; CHECK-SAME: (<2 x ptr addrspace(1)> [[P:%.*]], <2 x i32> [[M:%.*]]) {
220 ; CHECK-NEXT: [[PM:%.*]] = call <2 x ptr addrspace(1)> @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1)> [[P]], <2 x i32> [[M]])
221 ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint <2 x ptr addrspace(1)> [[PM]] to <2 x i64>
222 ; CHECK-NEXT: [[R:%.*]] = trunc <2 x i64> [[TMP1]] to <2 x i32>
223 ; CHECK-NEXT: ret <2 x i32> [[R]]
225 %pm = call <2 x ptr addrspace(1) > @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1) > %p, <2 x i32> %m)
226 %r = ptrtoint <2 x ptr addrspace(1) > %pm to <2 x i32>
230 define ptr addrspace(1) @ptrmask_is_null(ptr addrspace(1) align 32 %p) {
231 ; CHECK-LABEL: define ptr addrspace(1) @ptrmask_is_null
232 ; CHECK-SAME: (ptr addrspace(1) align 32 [[P:%.*]]) {
233 ; CHECK-NEXT: [[R:%.*]] = call align 4294967296 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P]], i32 0)
234 ; CHECK-NEXT: ret ptr addrspace(1) [[R]]
236 %r = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p, i32 31)
237 ret ptr addrspace(1) %r
240 define <2 x ptr addrspace(1) > @ptrmask_is_null_vec(<2 x ptr addrspace(1) > align 64 %p) {
241 ; CHECK-LABEL: define <2 x ptr addrspace(1)> @ptrmask_is_null_vec
242 ; CHECK-SAME: (<2 x ptr addrspace(1)> align 64 [[P:%.*]]) {
243 ; CHECK-NEXT: [[R:%.*]] = call <2 x ptr addrspace(1)> @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1)> [[P]], <2 x i32> <i32 31, i32 63>)
244 ; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[R]]
246 %r = call <2 x ptr addrspace(1) > @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1) > %p, <2 x i32> <i32 31, i32 63>)
247 ret <2 x ptr addrspace(1) > %r
250 define ptr addrspace(1) @ptrmask_is_null_fail(ptr addrspace(1) align 16 %p) {
251 ; CHECK-LABEL: define ptr addrspace(1) @ptrmask_is_null_fail
252 ; CHECK-SAME: (ptr addrspace(1) align 16 [[P:%.*]]) {
253 ; CHECK-NEXT: [[R:%.*]] = call align 16 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P]], i32 16)
254 ; CHECK-NEXT: ret ptr addrspace(1) [[R]]
256 %r = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p, i32 31)
257 ret ptr addrspace(1) %r
260 define <2 x ptr addrspace(1) > @ptrmask_is_null_vec_fail(<2 x ptr addrspace(1) > align 32 %p) {
261 ; CHECK-LABEL: define <2 x ptr addrspace(1)> @ptrmask_is_null_vec_fail
262 ; CHECK-SAME: (<2 x ptr addrspace(1)> align 32 [[P:%.*]]) {
263 ; CHECK-NEXT: [[R:%.*]] = call <2 x ptr addrspace(1)> @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1)> [[P]], <2 x i32> <i32 31, i32 63>)
264 ; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[R]]
266 %r = call <2 x ptr addrspace(1) > @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1) > %p, <2 x i32> <i32 31, i32 63>)
267 ret <2 x ptr addrspace(1) > %r
270 define ptr @ptrmask_maintain_provenance_i64(ptr %p0) {
271 ; CHECK-LABEL: define ptr @ptrmask_maintain_provenance_i64
272 ; CHECK-SAME: (ptr [[P0:%.*]]) {
273 ; CHECK-NEXT: [[R:%.*]] = call align 4294967296 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 0)
274 ; CHECK-NEXT: ret ptr [[R]]
276 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 0)
280 define ptr addrspace(1) @ptrmask_maintain_provenance_i32(ptr addrspace(1) %p0) {
281 ; CHECK-LABEL: define ptr addrspace(1) @ptrmask_maintain_provenance_i32
282 ; CHECK-SAME: (ptr addrspace(1) [[P0:%.*]]) {
283 ; CHECK-NEXT: [[R:%.*]] = call align 4294967296 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P0]], i32 0)
284 ; CHECK-NEXT: ret ptr addrspace(1) [[R]]
286 %r = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p0, i32 0)
287 ret ptr addrspace(1) %r
290 define ptr @ptrmask_is_nop0(ptr align 8 %p) {
291 ; CHECK-LABEL: define ptr @ptrmask_is_nop0
292 ; CHECK-SAME: (ptr align 8 [[P:%.*]]) {
293 ; CHECK-NEXT: ret ptr [[P]]
295 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -8)
299 define ptr @ptrmask_is_nop1(ptr align 8 %p) {
300 ; CHECK-LABEL: define ptr @ptrmask_is_nop1
301 ; CHECK-SAME: (ptr align 8 [[P:%.*]]) {
302 ; CHECK-NEXT: ret ptr [[P]]
304 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -4)
308 define ptr @ptrmask_to_modified_gep0(ptr align 8 %p) {
309 ; CHECK-LABEL: define ptr @ptrmask_to_modified_gep0
310 ; CHECK-SAME: (ptr align 8 [[P:%.*]]) {
311 ; CHECK-NEXT: [[PM:%.*]] = call align 16 ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -16)
312 ; CHECK-NEXT: ret ptr [[PM]]
314 %gep = getelementptr i8, ptr %p, i32 5
315 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -16)
319 define ptr @ptrmask_to_modified_gep1(ptr align 8 %p) {
320 ; CHECK-LABEL: define ptr @ptrmask_to_modified_gep1
321 ; CHECK-SAME: (ptr align 8 [[P:%.*]]) {
322 ; CHECK-NEXT: ret ptr [[P]]
324 %gep = getelementptr i8, ptr %p, i32 6
325 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -8)
329 define ptr @ptrmask_to_modified_gep2(ptr align 16 %p) {
330 ; CHECK-LABEL: define ptr @ptrmask_to_modified_gep2
331 ; CHECK-SAME: (ptr align 16 [[P:%.*]]) {
332 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P]], i64 12
333 ; CHECK-NEXT: ret ptr [[GEP1]]
335 %gep = getelementptr i8, ptr %p, i32 15
336 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -4)
340 define ptr @ptrmask_to_modified_gep4(ptr align 8 %p) {
341 ; CHECK-LABEL: define ptr @ptrmask_to_modified_gep4
342 ; CHECK-SAME: (ptr align 8 [[P:%.*]]) {
343 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P]], i64 24
344 ; CHECK-NEXT: [[PM:%.*]] = call align 16 ptr @llvm.ptrmask.p0.i64(ptr [[GEP1]], i64 -16)
345 ; CHECK-NEXT: ret ptr [[PM]]
347 %gep = getelementptr i8, ptr %p, i32 29
348 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -16)
352 define ptr @ptrmask_to_modified_gep5(ptr align 8 %p) {
353 ; CHECK-LABEL: define ptr @ptrmask_to_modified_gep5
354 ; CHECK-SAME: (ptr align 8 [[P:%.*]]) {
355 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P]], i64 24
356 ; CHECK-NEXT: ret ptr [[GEP1]]
358 %gep = getelementptr i8, ptr %p, i32 30
359 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -8)
363 define ptr @ptrmask_to_modified_gep6(ptr align 16 %p) {
364 ; CHECK-LABEL: define ptr @ptrmask_to_modified_gep6
365 ; CHECK-SAME: (ptr align 16 [[P:%.*]]) {
366 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P]], i64 28
367 ; CHECK-NEXT: ret ptr [[GEP1]]
369 %gep = getelementptr i8, ptr %p, i32 31
370 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -4)
374 define ptr @ptrmask_to_modified_gep_indirect0(ptr align 16 %p) {
375 ; CHECK-LABEL: define ptr @ptrmask_to_modified_gep_indirect0
376 ; CHECK-SAME: (ptr align 16 [[P:%.*]]) {
377 ; 44 from 4*sizeof(i32) + (31 & -4)
378 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P]], i64 44
379 ; CHECK-NEXT: ret ptr [[GEP1]]
381 %gep0 = getelementptr i32, ptr %p, i32 4
382 %gep1 = getelementptr i8, ptr %gep0, i32 31
383 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep1, i64 -4)
387 define ptr @ptrmask_to_modified_gep_indirect1(ptr %p) {
388 ; CHECK-LABEL: define ptr @ptrmask_to_modified_gep_indirect1
389 ; CHECK-SAME: (ptr [[P:%.*]]) {
391 ; CHECK-NEXT: [[R:%.*]] = call align 16 ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -16)
392 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[R]], i64 32
393 ; CHECK-NEXT: ret ptr [[GEP]]
395 %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -16)
396 %pgep = getelementptr i8, ptr %pm0, i64 33
397 %r = call ptr @llvm.ptrmask.p0.i64(ptr %pgep, i64 -16)
401 define ptr @ptrmask_to_modified_gep_zero_argument() {
402 ; CHECK-LABEL: define ptr @ptrmask_to_modified_gep_zero_argument() {
403 ; CHECK-NEXT: [[P:%.*]] = call nonnull align 4 ptr @llvm.ptrmask.p0.i64(ptr nonnull inttoptr (i64 31 to ptr), i64 28)
404 ; CHECK-NEXT: ret ptr [[P]]
406 %gep = getelementptr inbounds i8, ptr null, i32 31
407 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -4)
411 define ptr @ptrmask_to_preserves_inbounds(ptr align 16 %p) {
412 ; CHECK-LABEL: define ptr @ptrmask_to_preserves_inbounds
413 ; CHECK-SAME: (ptr align 16 [[P:%.*]]) {
414 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 28
415 ; CHECK-NEXT: ret ptr [[GEP1]]
417 %gep = getelementptr inbounds i8, ptr %p, i32 31
418 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -4)
422 define ptr @ptrmask_of_gep_requires_i8(ptr align 8 %p) {
423 ; CHECK-LABEL: define ptr @ptrmask_of_gep_requires_i8
424 ; CHECK-SAME: (ptr align 8 [[P:%.*]]) {
425 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P]], i64 8
426 ; CHECK-NEXT: [[PM:%.*]] = call align 16 ptr @llvm.ptrmask.p0.i64(ptr [[GEP1]], i64 -16)
427 ; CHECK-NEXT: ret ptr [[PM]]
429 %gep = getelementptr i16, ptr %p, i32 5
430 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -16)
434 define <2 x ptr> @ptrmask_of_gep_vector_type_unimplemented(<2 x ptr> align 8 %p) {
435 ; CHECK-LABEL: define <2 x ptr> @ptrmask_of_gep_vector_type_unimplemented
436 ; CHECK-SAME: (<2 x ptr> align 8 [[P:%.*]]) {
437 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, <2 x ptr> [[P]], i64 17
438 ; CHECK-NEXT: [[PM:%.*]] = call align 32 <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> [[GEP]], <2 x i64> <i64 -96, i64 -96>)
439 ; CHECK-NEXT: ret <2 x ptr> [[PM]]
441 %gep = getelementptr i8, <2 x ptr> %p, i32 17
442 %pm = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %gep, <2 x i64> <i64 -96, i64 -96>)
446 define ptr @ptrmask_is_useless0(i64 %i, i64 %m) {
447 ; CHECK-LABEL: define ptr @ptrmask_is_useless0
448 ; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {
449 ; CHECK-NEXT: [[I0:%.*]] = and i64 [[I]], -4
450 ; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr
451 ; CHECK-NEXT: [[R:%.*]] = call align 4 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[M]])
452 ; CHECK-NEXT: ret ptr [[R]]
456 %p0 = inttoptr i64 %i0 to ptr
457 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)
461 define ptr @ptrmask_is_useless1(i64 %i, i64 %m) {
462 ; CHECK-LABEL: define ptr @ptrmask_is_useless1
463 ; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {
464 ; CHECK-NEXT: [[I0:%.*]] = and i64 [[I]], -8
465 ; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr
466 ; CHECK-NEXT: [[R:%.*]] = call align 8 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[M]])
467 ; CHECK-NEXT: ret ptr [[R]]
471 %p0 = inttoptr i64 %i0 to ptr
472 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)
476 define ptr @ptrmask_is_useless2(i64 %i, i64 %m) {
477 ; CHECK-LABEL: define ptr @ptrmask_is_useless2
478 ; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {
479 ; CHECK-NEXT: [[I0:%.*]] = and i64 [[I]], 31
480 ; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr
481 ; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[M]])
482 ; CHECK-NEXT: ret ptr [[R]]
484 %m0 = and i64 %m, 127
486 %p0 = inttoptr i64 %i0 to ptr
487 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)
491 define ptr @ptrmask_is_useless3(i64 %i, i64 %m) {
492 ; CHECK-LABEL: define ptr @ptrmask_is_useless3
493 ; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {
494 ; CHECK-NEXT: [[I0:%.*]] = and i64 [[I]], 127
495 ; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr
496 ; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[M]])
497 ; CHECK-NEXT: ret ptr [[R]]
499 %m0 = and i64 %m, 127
500 %i0 = and i64 %i, 127
501 %p0 = inttoptr i64 %i0 to ptr
502 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)
506 define ptr @ptrmask_is_useless4(i64 %i, i64 %m) {
507 ; CHECK-LABEL: define ptr @ptrmask_is_useless4
508 ; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {
509 ; CHECK-NEXT: [[I0:%.*]] = and i64 [[I]], -4
510 ; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr
511 ; CHECK-NEXT: ret ptr [[P0]]
515 %p0 = inttoptr i64 %i0 to ptr
516 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)
520 define <2 x ptr> @ptrmask_is_useless_vec(<2 x i64> %i, <2 x i64> %m) {
521 ; CHECK-LABEL: define <2 x ptr> @ptrmask_is_useless_vec
522 ; CHECK-SAME: (<2 x i64> [[I:%.*]], <2 x i64> [[M:%.*]]) {
523 ; CHECK-NEXT: [[I0:%.*]] = and <2 x i64> [[I]], <i64 31, i64 31>
524 ; CHECK-NEXT: [[P0:%.*]] = inttoptr <2 x i64> [[I0]] to <2 x ptr>
525 ; CHECK-NEXT: [[R:%.*]] = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> [[P0]], <2 x i64> [[M]])
526 ; CHECK-NEXT: ret <2 x ptr> [[R]]
528 %m0 = and <2 x i64> %m, <i64 127, i64 127>
529 %i0 = and <2 x i64> %i, <i64 31, i64 31>
530 %p0 = inttoptr <2 x i64> %i0 to <2 x ptr>
531 %r = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %p0, <2 x i64> %m0)
535 define <2 x ptr> @ptrmask_is_useless_vec_todo(<2 x i64> %i, <2 x i64> %m) {
536 ; CHECK-LABEL: define <2 x ptr> @ptrmask_is_useless_vec_todo
537 ; CHECK-SAME: (<2 x i64> [[I:%.*]], <2 x i64> [[M:%.*]]) {
538 ; CHECK-NEXT: [[I0:%.*]] = and <2 x i64> [[I]], <i64 31, i64 127>
539 ; CHECK-NEXT: [[P0:%.*]] = inttoptr <2 x i64> [[I0]] to <2 x ptr>
540 ; CHECK-NEXT: [[R:%.*]] = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> [[P0]], <2 x i64> [[M]])
541 ; CHECK-NEXT: ret <2 x ptr> [[R]]
543 %m0 = and <2 x i64> %m, <i64 127, i64 127>
544 %i0 = and <2 x i64> %i, <i64 31, i64 127>
545 %p0 = inttoptr <2 x i64> %i0 to <2 x ptr>
546 %r = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %p0, <2 x i64> %m0)
550 define ptr @ptrmask_is_useless_fail0(i64 %i, i64 %m) {
551 ; CHECK-LABEL: define ptr @ptrmask_is_useless_fail0
552 ; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {
553 ; CHECK-NEXT: [[M0:%.*]] = and i64 [[M]], -4
554 ; CHECK-NEXT: [[I0:%.*]] = or i64 [[I]], -4
555 ; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr
556 ; CHECK-NEXT: [[R:%.*]] = call align 4 ptr @llvm.ptrmask.p0.i64(ptr nonnull [[P0]], i64 [[M0]])
557 ; CHECK-NEXT: ret ptr [[R]]
561 %p0 = inttoptr i64 %i0 to ptr
562 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)
566 define ptr @ptrmask_is_useless_fail1(i64 %i, i64 %m) {
567 ; CHECK-LABEL: define ptr @ptrmask_is_useless_fail1
568 ; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {
569 ; CHECK-NEXT: [[M0:%.*]] = and i64 [[M]], 127
570 ; CHECK-NEXT: [[I0:%.*]] = and i64 [[I]], 511
571 ; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr
572 ; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[M0]])
573 ; CHECK-NEXT: ret ptr [[R]]
575 %m0 = and i64 %m, 127
576 %i0 = and i64 %i, 511
577 %p0 = inttoptr i64 %i0 to ptr
578 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)