Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / GVN / non-integral-pointers.ll
blob5f2aef4f4435029bce9bb8d16d2baa6bf5870521
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=gvn -S < %s | FileCheck %s
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4:5"
5 target triple = "x86_64-unknown-linux-gnu"
7 define void @f0(i1 %alwaysFalse, i64 %val, ptr %loc) {
8 ; CHECK-LABEL: @f0(
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    store i64 [[VAL:%.*]], ptr [[LOC:%.*]], align 8
11 ; CHECK-NEXT:    br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
12 ; CHECK:       neverTaken:
13 ; CHECK-NEXT:    [[PTR:%.*]] = load ptr addrspace(4), ptr [[LOC]], align 8
14 ; CHECK-NEXT:    store i8 5, ptr addrspace(4) [[PTR]], align 1
15 ; CHECK-NEXT:    ret void
16 ; CHECK:       alwaysTaken:
17 ; CHECK-NEXT:    ret void
19   entry:
20   store i64 %val, ptr %loc
21   br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
23   neverTaken:
24   %ptr = load ptr addrspace(4), ptr %loc
25   store i8 5, ptr addrspace(4) %ptr
26   ret void
28   alwaysTaken:
29   ret void
32 define i64 @f1(i1 %alwaysFalse, ptr addrspace(4) %val, ptr %loc) {
33 ; CHECK-LABEL: @f1(
34 ; CHECK-NEXT:  entry:
35 ; CHECK-NEXT:    store ptr addrspace(4) [[VAL:%.*]], ptr [[LOC:%.*]], align 8
36 ; CHECK-NEXT:    br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
37 ; CHECK:       neverTaken:
38 ; CHECK-NEXT:    [[INT:%.*]] = load i64, ptr [[LOC]], align 8
39 ; CHECK-NEXT:    ret i64 [[INT]]
40 ; CHECK:       alwaysTaken:
41 ; CHECK-NEXT:    ret i64 42
43   entry:
44   store ptr addrspace(4) %val, ptr %loc
45   br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
47   neverTaken:
48   %int = load i64, ptr %loc
49   ret i64 %int
51   alwaysTaken:
52   ret i64 42
55 ;; Note: For terseness, we stop using the %alwaysfalse trick for the
56 ;; tests below and just exercise the bits of forwarding logic directly.
58 declare void @llvm.memset.p4.i64(ptr addrspace(4) nocapture, i8, i64, i1) nounwind
60 ; Can't forward as the load might be dead.  (Pretend we wrote out the alwaysfalse idiom above.)
61 define ptr addrspace(4) @neg_forward_memset(ptr addrspace(4) %loc) {
62 ; CHECK-LABEL: @neg_forward_memset(
63 ; CHECK-NEXT:  entry:
64 ; CHECK-NEXT:    call void @llvm.memset.p4.i64(ptr addrspace(4) align 4 [[LOC:%.*]], i8 7, i64 8, i1 false)
65 ; CHECK-NEXT:    [[REF:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[LOC]], align 8
66 ; CHECK-NEXT:    ret ptr addrspace(4) [[REF]]
68   entry:
69   call void @llvm.memset.p4.i64(ptr addrspace(4) align 4 %loc, i8 7, i64 8, i1 false)
70   %ref = load ptr addrspace(4), ptr addrspace(4) %loc
71   ret ptr addrspace(4) %ref
74 define <1 x ptr addrspace(4)> @neg_forward_memset_vload(ptr addrspace(4) %loc) {
75 ; CHECK-LABEL: @neg_forward_memset_vload(
76 ; CHECK-NEXT:  entry:
77 ; CHECK-NEXT:    call void @llvm.memset.p4.i64(ptr addrspace(4) align 4 [[LOC:%.*]], i8 7, i64 8, i1 false)
78 ; CHECK-NEXT:    [[REF:%.*]] = load <1 x ptr addrspace(4)>, ptr addrspace(4) [[LOC]], align 8
79 ; CHECK-NEXT:    ret <1 x ptr addrspace(4)> [[REF]]
81   entry:
82   call void @llvm.memset.p4.i64(ptr addrspace(4) align 4 %loc, i8 7, i64 8, i1 false)
83   %ref = load <1 x ptr addrspace(4)>, ptr addrspace(4) %loc
84   ret <1 x ptr addrspace(4)> %ref
88 ; Can forward since we can do so w/o breaking types
89 define ptr addrspace(4) @forward_memset_zero(ptr addrspace(4) %loc) {
90 ; CHECK-LABEL: @forward_memset_zero(
91 ; CHECK-NEXT:  entry:
92 ; CHECK-NEXT:    call void @llvm.memset.p4.i64(ptr addrspace(4) align 4 [[LOC:%.*]], i8 0, i64 8, i1 false)
93 ; CHECK-NEXT:    ret ptr addrspace(4) null
95   entry:
96   call void @llvm.memset.p4.i64(ptr addrspace(4) align 4 %loc, i8 0, i64 8, i1 false)
97   %ref = load ptr addrspace(4), ptr addrspace(4) %loc
98   ret ptr addrspace(4) %ref
101 ; Can't forward as the load might be dead.  (Pretend we wrote out the alwaysfalse idiom above.)
102 define ptr addrspace(4) @neg_forward_store(ptr addrspace(4) %loc) {
103 ; CHECK-LABEL: @neg_forward_store(
104 ; CHECK-NEXT:  entry:
105 ; CHECK-NEXT:    store i64 5, ptr addrspace(4) [[LOC:%.*]], align 8
106 ; CHECK-NEXT:    [[REF:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[LOC]], align 8
107 ; CHECK-NEXT:    ret ptr addrspace(4) [[REF]]
109   entry:
110   store i64 5, ptr addrspace(4) %loc
111   %ref = load ptr addrspace(4), ptr addrspace(4) %loc
112   ret ptr addrspace(4) %ref
115 define <1 x ptr addrspace(4)> @neg_forward_store_vload(ptr addrspace(4) %loc) {
116 ; CHECK-LABEL: @neg_forward_store_vload(
117 ; CHECK-NEXT:  entry:
118 ; CHECK-NEXT:    store i64 5, ptr addrspace(4) [[LOC:%.*]], align 8
119 ; CHECK-NEXT:    [[REF:%.*]] = load <1 x ptr addrspace(4)>, ptr addrspace(4) [[LOC]], align 8
120 ; CHECK-NEXT:    ret <1 x ptr addrspace(4)> [[REF]]
122   entry:
123   store i64 5, ptr addrspace(4) %loc
124   %ref = load <1 x ptr addrspace(4)>, ptr addrspace(4) %loc
125   ret <1 x ptr addrspace(4)> %ref
128 ; Nulls have known bit patterns, so we can forward
129 define ptr addrspace(4) @forward_store_zero(ptr addrspace(4) %loc) {
130 ; CHECK-LABEL: @forward_store_zero(
131 ; CHECK-NEXT:  entry:
132 ; CHECK-NEXT:    store i64 0, ptr addrspace(4) [[LOC:%.*]], align 8
133 ; CHECK-NEXT:    ret ptr addrspace(4) null
135   entry:
136   store i64 0, ptr addrspace(4) %loc
137   %ref = load ptr addrspace(4), ptr addrspace(4) %loc
138   ret ptr addrspace(4) %ref
141 ; Nulls have known bit patterns, so we can forward
142 define ptr addrspace(4) @forward_store_zero2(ptr addrspace(4) %loc) {
143 ; CHECK-LABEL: @forward_store_zero2(
144 ; CHECK-NEXT:  entry:
145 ; CHECK-NEXT:    store <2 x i32> zeroinitializer, ptr addrspace(4) [[LOC:%.*]], align 8
146 ; CHECK-NEXT:    ret ptr addrspace(4) null
148   entry:
149   store <2 x i32> zeroinitializer, ptr addrspace(4) %loc
150   %ref = load ptr addrspace(4), ptr addrspace(4) %loc
151   ret ptr addrspace(4) %ref
156 @NonZeroConstant = constant <4 x i64> <i64 3, i64 3, i64 3, i64 3>
157 @NonZeroConstant2 = constant <4 x ptr addrspace(4)> <
158   ptr addrspace(4) getelementptr (i64, ptr addrspace(4) null, i32 3),
159   ptr addrspace(4) getelementptr (i64, ptr addrspace(4) null, i32 3),
160   ptr addrspace(4) getelementptr (i64, ptr addrspace(4) null, i32 3),
161   ptr addrspace(4) getelementptr (i64, ptr addrspace(4) null, i32 3)>
162 @ZeroConstant = constant <4 x i64> zeroinitializer
165 ; Can't forward as the load might be dead.  (Pretend we wrote out the alwaysfalse idiom above.)
166 define ptr addrspace(4) @neg_forward_memcopy(ptr addrspace(4) %loc) {
167 ; CHECK-LABEL: @neg_forward_memcopy(
168 ; CHECK-NEXT:  entry:
169 ; CHECK-NEXT:    call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 [[LOC:%.*]], ptr @NonZeroConstant, i64 8, i1 false)
170 ; CHECK-NEXT:    [[REF:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[LOC]], align 8
171 ; CHECK-NEXT:    ret ptr addrspace(4) [[REF]]
173 entry:
174   call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 %loc, ptr @NonZeroConstant, i64 8, i1 false)
175   %ref = load ptr addrspace(4), ptr addrspace(4) %loc
176   ret ptr addrspace(4) %ref
179 define ptr addrspace(4) @neg_forward_memcopy2(ptr addrspace(4) %loc) {
180 ; CHECK-LABEL: @neg_forward_memcopy2(
181 ; CHECK-NEXT:  entry:
182 ; CHECK-NEXT:    call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 [[LOC:%.*]], ptr @NonZeroConstant, i64 8, i1 false)
183 ; CHECK-NEXT:    [[REF:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[LOC]], align 8
184 ; CHECK-NEXT:    ret ptr addrspace(4) [[REF]]
186 entry:
187   call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 %loc, ptr @NonZeroConstant, i64 8, i1 false)
188   %ref = load ptr addrspace(4), ptr addrspace(4) %loc
189   ret ptr addrspace(4) %ref
192 define ptr addrspace(4) @forward_memcopy(ptr addrspace(4) %loc) {
193 ; CHECK-LABEL: @forward_memcopy(
194 ; CHECK-NEXT:  entry:
195 ; CHECK-NEXT:    call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 [[LOC:%.*]], ptr @NonZeroConstant2, i64 8, i1 false)
196 ; CHECK-NEXT:    ret ptr addrspace(4) getelementptr (i64, ptr addrspace(4) null, i32 3)
198 entry:
199   call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 %loc, ptr @NonZeroConstant2, i64 8, i1 false)
200   %ref = load ptr addrspace(4), ptr addrspace(4) %loc
201   ret ptr addrspace(4) %ref
204 define ptr addrspace(4) @forward_memcopy2(ptr addrspace(4) %loc) {
205 ; CHECK-LABEL: @forward_memcopy2(
206 ; CHECK-NEXT:  entry:
207 ; CHECK-NEXT:    call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 [[LOC:%.*]], ptr @NonZeroConstant2, i64 8, i1 false)
208 ; CHECK-NEXT:    ret ptr addrspace(4) getelementptr (i64, ptr addrspace(4) null, i32 3)
210 entry:
211   call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 %loc, ptr @NonZeroConstant2, i64 8, i1 false)
212   %ref = load ptr addrspace(4), ptr addrspace(4) %loc
213   ret ptr addrspace(4) %ref
216 define <1 x ptr addrspace(4)> @neg_forward_memcpy_vload(ptr addrspace(4) %loc) {
217 ; CHECK-LABEL: @neg_forward_memcpy_vload(
218 ; CHECK-NEXT:  entry:
219 ; CHECK-NEXT:    call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 [[LOC:%.*]], ptr @NonZeroConstant, i64 8, i1 false)
220 ; CHECK-NEXT:    [[REF:%.*]] = load <1 x ptr addrspace(4)>, ptr addrspace(4) [[LOC]], align 8
221 ; CHECK-NEXT:    ret <1 x ptr addrspace(4)> [[REF]]
223 entry:
224   call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 %loc, ptr @NonZeroConstant, i64 8, i1 false)
225   %ref = load <1 x ptr addrspace(4)>, ptr addrspace(4) %loc
226   ret <1 x ptr addrspace(4)> %ref
229 define <4 x ptr addrspace(4)> @neg_forward_memcpy_vload2(ptr addrspace(4) %loc) {
230 ; CHECK-LABEL: @neg_forward_memcpy_vload2(
231 ; CHECK-NEXT:  entry:
232 ; CHECK-NEXT:    call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 [[LOC:%.*]], ptr @NonZeroConstant, i64 32, i1 false)
233 ; CHECK-NEXT:    [[REF:%.*]] = load <4 x ptr addrspace(4)>, ptr addrspace(4) [[LOC]], align 32
234 ; CHECK-NEXT:    ret <4 x ptr addrspace(4)> [[REF]]
236 entry:
237   call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 %loc, ptr @NonZeroConstant, i64 32, i1 false)
238   %ref = load <4 x ptr addrspace(4)>, ptr addrspace(4) %loc
239   ret <4 x ptr addrspace(4)> %ref
242 define <4 x i64> @neg_forward_memcpy_vload3(ptr addrspace(4) %loc) {
243 ; CHECK-LABEL: @neg_forward_memcpy_vload3(
244 ; CHECK-NEXT:  entry:
245 ; CHECK-NEXT:    call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 [[LOC:%.*]], ptr @NonZeroConstant2, i64 32, i1 false)
246 ; CHECK-NEXT:    [[REF:%.*]] = load <4 x i64>, ptr addrspace(4) [[LOC]], align 32
247 ; CHECK-NEXT:    ret <4 x i64> [[REF]]
249 entry:
250   call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 %loc, ptr @NonZeroConstant2, i64 32, i1 false)
251   %ref = load <4 x i64>, ptr addrspace(4) %loc
252   ret <4 x i64> %ref
255 define <1 x ptr addrspace(4)> @forward_memcpy_vload3(ptr addrspace(4) %loc) {
256 ; CHECK-LABEL: @forward_memcpy_vload3(
257 ; CHECK-NEXT:  entry:
258 ; CHECK-NEXT:    call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 [[LOC:%.*]], ptr @NonZeroConstant2, i64 32, i1 false)
259 ; CHECK-NEXT:    ret <1 x ptr addrspace(4)> <ptr addrspace(4) getelementptr (i64, ptr addrspace(4) null, i32 3)>
261 entry:
262   call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 %loc, ptr @NonZeroConstant2, i64 32, i1 false)
263   %ref = load <4 x ptr addrspace(4)>, ptr addrspace(4) %loc
264   %val = extractelement <4 x ptr addrspace(4)> %ref, i32 0
265   %ret = insertelement <1 x ptr addrspace(4)> undef, ptr addrspace(4) %val, i32 0
266   ret <1 x ptr addrspace(4)> %ret
269 ; Can forward since we can do so w/o breaking types
270 define ptr addrspace(4) @forward_memcpy_zero(ptr addrspace(4) %loc) {
271 ; CHECK-LABEL: @forward_memcpy_zero(
272 ; CHECK-NEXT:  entry:
273 ; CHECK-NEXT:    call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 [[LOC:%.*]], ptr @ZeroConstant, i64 8, i1 false)
274 ; CHECK-NEXT:    ret ptr addrspace(4) null
276 entry:
277   call void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) align 4 %loc, ptr @ZeroConstant, i64 8, i1 false)
278   %ref = load ptr addrspace(4), ptr addrspace(4) %loc
279   ret ptr addrspace(4) %ref
282 declare void @llvm.memcpy.p4.p0.i64(ptr addrspace(4) nocapture, ptr nocapture, i64, i1) nounwind
285 ; Same as the neg_forward_store cases, but for non defs.
286 ; (Pretend we wrote out the alwaysfalse idiom above.)
287 define ptr addrspace(4) @neg_store_clobber(ptr addrspace(4) %loc) {
288 ; CHECK-LABEL: @neg_store_clobber(
289 ; CHECK-NEXT:  entry:
290 ; CHECK-NEXT:    store <2 x i64> <i64 4, i64 4>, ptr addrspace(4) [[LOC:%.*]], align 16
291 ; CHECK-NEXT:    [[LOC_OFF:%.*]] = getelementptr ptr addrspace(4), ptr addrspace(4) [[LOC]], i64 1
292 ; CHECK-NEXT:    [[REF:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[LOC_OFF]], align 8
293 ; CHECK-NEXT:    ret ptr addrspace(4) [[REF]]
295 entry:
296   store <2 x i64> <i64 4, i64 4>, ptr addrspace(4) %loc
297   %loc.off = getelementptr ptr addrspace(4), ptr addrspace(4) %loc, i64 1
298   %ref = load ptr addrspace(4), ptr addrspace(4) %loc.off
299   ret ptr addrspace(4) %ref
302 declare void @use(<2 x i64>) inaccessiblememonly
304 ; Same as the neg_forward_store cases, but for non defs.
305 ; (Pretend we wrote out the alwaysfalse idiom above.)
306 define ptr addrspace(4) @neg_load_clobber(ptr addrspace(4) %loc) {
307 ; CHECK-LABEL: @neg_load_clobber(
308 ; CHECK-NEXT:  entry:
309 ; CHECK-NEXT:    [[V:%.*]] = load <2 x i64>, ptr addrspace(4) [[LOC:%.*]], align 16
310 ; CHECK-NEXT:    call void @use(<2 x i64> [[V]])
311 ; CHECK-NEXT:    [[LOC_OFF:%.*]] = getelementptr ptr addrspace(4), ptr addrspace(4) [[LOC]], i64 1
312 ; CHECK-NEXT:    [[REF:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[LOC_OFF]], align 8
313 ; CHECK-NEXT:    ret ptr addrspace(4) [[REF]]
315 entry:
316   %v = load <2 x i64>, ptr addrspace(4) %loc
317   call void @use(<2 x i64> %v)
318   %loc.off = getelementptr ptr addrspace(4), ptr addrspace(4) %loc, i64 1
319   %ref = load ptr addrspace(4), ptr addrspace(4) %loc.off
320   ret ptr addrspace(4) %ref
323 define ptr addrspace(4) @store_clobber_zero(ptr addrspace(4) %loc) {
324 ; CHECK-LABEL: @store_clobber_zero(
325 ; CHECK-NEXT:  entry:
326 ; CHECK-NEXT:    store <2 x i64> zeroinitializer, ptr addrspace(4) [[LOC:%.*]], align 16
327 ; CHECK-NEXT:    [[LOC_OFF:%.*]] = getelementptr ptr addrspace(4), ptr addrspace(4) [[LOC]], i64 1
328 ; CHECK-NEXT:    ret ptr addrspace(4) null
330 entry:
331   store <2 x i64> zeroinitializer, ptr addrspace(4) %loc
332   %loc.off = getelementptr ptr addrspace(4), ptr addrspace(4) %loc, i64 1
333   %ref = load ptr addrspace(4), ptr addrspace(4) %loc.off
334   ret ptr addrspace(4) %ref
338 define void @smaller_vector(ptr %p) {
339 ; CHECK-LABEL: @smaller_vector(
340 ; CHECK-NEXT:  entry:
341 ; CHECK-NEXT:    [[V4:%.*]] = load <4 x ptr addrspace(4)>, ptr [[P:%.*]], align 32
342 ; CHECK-NEXT:    [[V2:%.*]] = load <2 x ptr addrspace(4)>, ptr [[P]], align 32
343 ; CHECK-NEXT:    call void @use.v2(<2 x ptr addrspace(4)> [[V2]])
344 ; CHECK-NEXT:    call void @use.v4(<4 x ptr addrspace(4)> [[V4]])
345 ; CHECK-NEXT:    ret void
347 entry:
348   %v4 = load <4 x ptr addrspace(4)>, ptr %p, align 32
349   %v2 = load <2 x ptr addrspace(4)>, ptr %p, align 32
350   call void @use.v2(<2 x ptr addrspace(4)> %v2)
351   call void @use.v4(<4 x ptr addrspace(4)> %v4)
352   ret void
355 define ptr addrspace(4) @vector_extract(ptr %p) {
356 ; CHECK-LABEL: @vector_extract(
357 ; CHECK-NEXT:  entry:
358 ; CHECK-NEXT:    [[V4:%.*]] = load <4 x ptr addrspace(4)>, ptr [[P:%.*]], align 32
359 ; CHECK-NEXT:    [[RES:%.*]] = load ptr addrspace(4), ptr [[P]], align 32
360 ; CHECK-NEXT:    call void @use.v4(<4 x ptr addrspace(4)> [[V4]])
361 ; CHECK-NEXT:    ret ptr addrspace(4) [[RES]]
363 entry:
364   %v4 = load <4 x ptr addrspace(4)>, ptr %p, align 32
365   %res = load ptr addrspace(4), ptr %p, align 32
366   call void @use.v4(<4 x ptr addrspace(4)> %v4)
367   ret ptr addrspace(4) %res
370 declare void @use.v2(<2 x ptr addrspace(4)>)
371 declare void @use.v4(<4 x ptr addrspace(4)>)
372 define ptr addrspace(5) @multini(i1 %alwaysFalse, ptr addrspace(4) %val, ptr %loc) {
373 ; CHECK-LABEL: @multini(
374 ; CHECK-NEXT:  entry:
375 ; CHECK-NEXT:    store ptr addrspace(4) [[VAL:%.*]], ptr [[LOC:%.*]], align 8
376 ; CHECK-NEXT:    br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
377 ; CHECK:       neverTaken:
378 ; CHECK-NEXT:    [[DIFFERENTAS:%.*]] = load ptr addrspace(5), ptr [[LOC]], align 8
379 ; CHECK-NEXT:    ret ptr addrspace(5) [[DIFFERENTAS]]
380 ; CHECK:       alwaysTaken:
381 ; CHECK-NEXT:    ret ptr addrspace(5) null
383 entry:
384   store ptr addrspace(4) %val, ptr %loc
385   br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
387 neverTaken:
388   %differentas = load ptr addrspace(5), ptr %loc
389   ret ptr addrspace(5) %differentas
391 alwaysTaken:
392   ret ptr addrspace(5) null