Skip to content

Commit ca97396

Browse files
committed
Add metadata-copying tests
1 parent e8716bc commit ca97396

File tree

2 files changed

+306
-39
lines changed

2 files changed

+306
-39
lines changed
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=instcombine %s | FileCheck %s
2+
3+
@test.data = private unnamed_addr addrspace(2) constant [8 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7], align 4
4+
@test.ptrdata = private unnamed_addr addrspace(2) constant [8 x ptr] [ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null], align 8
5+
6+
; Verify that InstCombine copies range metadata when cloning a load as part of
7+
; replacing an alloca initialized via memcpy from a constant in another
8+
; address space. OK
9+
define i32 @copy_range_metadata_after_memcpy(i64 %x) {
10+
; CHECK-LABEL: define i32 @copy_range_metadata_after_memcpy(
11+
; CHECK-SAME: i64 [[X:%.*]]) {
12+
; CHECK-NEXT: entry:
13+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr addrspace(2) @test.data, i64 [[X]]
14+
; CHECK-NEXT: [[L:%.*]] = load i32, ptr addrspace(2) [[ARRAYIDX]], align 4, !range [[RNG0:![0-9]+]]
15+
; CHECK-NEXT: ret i32 [[L]]
16+
;
17+
entry:
18+
%data = alloca [8 x i32], align 4, addrspace(5)
19+
call void @llvm.memcpy.p5.p2.i64(ptr addrspace(5) align 4 %data, ptr addrspace(2) align 4 @test.data, i64 32, i1 false)
20+
%arrayidx = getelementptr inbounds [8 x i32], ptr addrspace(5) %data, i64 0, i64 %x
21+
%l = load i32, ptr addrspace(5) %arrayidx, align 4, !range !0
22+
ret i32 %l
23+
}
24+
25+
26+
27+
declare void @llvm.memcpy.p5.p2.i64(ptr addrspace(5) nocapture writeonly, ptr addrspace(2) nocapture readonly, i64, i1)
28+
29+
!0 = !{i32 0, i32 100}
30+
31+
; Verify TBAA metadata on a cloned load is preserved. OK
32+
define i32 @copy_tbaa_metadata_after_memcpy(i64 %x, ptr addrspace(5) %sink) {
33+
; CHECK-LABEL: define i32 @copy_tbaa_metadata_after_memcpy(
34+
; CHECK-SAME: i64 [[X:%.*]], ptr addrspace(5) [[SINK:%.*]]) {
35+
; CHECK-NEXT: entry:
36+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr addrspace(2) @test.data, i64 [[X]]
37+
; CHECK-NEXT: [[L:%.*]] = load i32, ptr addrspace(2) [[ARRAYIDX]], align 4, !tbaa [[TBAA0:![0-9]+]]
38+
; CHECK-NEXT: store i32 [[L]], ptr addrspace(5) [[SINK]], align 4
39+
; CHECK-NEXT: ret i32 [[L]]
40+
;
41+
entry:
42+
%data = alloca [8 x i32], align 4, addrspace(5)
43+
call void @llvm.memcpy.p5.p2.i64(ptr addrspace(5) align 4 %data, ptr addrspace(2) align 4 @test.data, i64 32, i1 false)
44+
%arrayidx = getelementptr inbounds [8 x i32], ptr addrspace(5) %data, i64 0, i64 %x
45+
%l = load i32, ptr addrspace(5) %arrayidx, align 4, !tbaa !1
46+
store i32 %l, ptr addrspace(5) %sink, align 4
47+
ret i32 %l
48+
}
49+
50+
!1 = !{!2, !2, i64 0}
51+
!2 = !{!"scalar type", !3}
52+
!3 = !{!"root"}
53+
54+
; CHECK: [[TBAA0]] = !{[[TBAATY:![0-9]+]], [[TBAATY]], i64 0}
55+
; CHECK: [[TBAATY]] = !{!"scalar type", [[TBAAROOT:![0-9]+]]}
56+
; CHECK: [[TBAAROOT]] = !{!"root"}
57+
58+
; Verify dereferenceable_or_null metadata on a cloned load is preserved
59+
; when the loaded value type is a pointer. OK
60+
define ptr @copy_deref_or_null_metadata_after_memcpy(i64 %x) {
61+
; CHECK-LABEL: define ptr @copy_deref_or_null_metadata_after_memcpy(
62+
; CHECK-SAME: i64 [[X:%.*]]) {
63+
; CHECK-NEXT: entry:
64+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr addrspace(2) @test.ptrdata, i64 [[X]]
65+
; CHECK-NEXT: [[L:%.*]] = load ptr, ptr addrspace(2) [[ARRAYIDX]], align 8, !dereferenceable_or_null [[DEREF_OR_NULL:![0-9]+]]
66+
; CHECK-NEXT: ret ptr [[L]]
67+
;
68+
entry:
69+
%data = alloca [8 x ptr], align 8, addrspace(5)
70+
call void @llvm.memcpy.p5.p2.i64(ptr addrspace(5) align 8 %data, ptr addrspace(2) align 8 @test.ptrdata, i64 64, i1 false)
71+
%arrayidx = getelementptr inbounds [8 x ptr], ptr addrspace(5) %data, i64 0, i64 %x
72+
%l = load ptr, ptr addrspace(5) %arrayidx, align 8, !dereferenceable_or_null !4
73+
ret ptr %l
74+
}
75+
76+
!4 = !{i64 8}
77+
78+
; CHECK: [[DEREF_OR_NULL]] = !{i64 8}
79+
80+
; Verify nonnull metadata on a cloned load is preserved
81+
; when the loaded value type is a pointer. OK
82+
define ptr @copy_nonnull_metadata_after_memcpy(i64 %x) {
83+
; CHECK-LABEL: define ptr @copy_nonnull_metadata_after_memcpy(
84+
; CHECK-SAME: i64 [[X:%.*]]) {
85+
; CHECK-NEXT: entry:
86+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr addrspace(2) @test.ptrdata, i64 [[X]]
87+
; CHECK-NEXT: [[L:%.*]] = load ptr, ptr addrspace(2) [[ARRAYIDX]], align 8, !nonnull [[NONNULL:![0-9]+]]
88+
; CHECK-NEXT: ret ptr [[L]]
89+
;
90+
entry:
91+
%data = alloca [8 x ptr], align 8, addrspace(5)
92+
call void @llvm.memcpy.p5.p2.i64(ptr addrspace(5) align 8 %data, ptr addrspace(2) align 8 @test.ptrdata, i64 64, i1 false)
93+
%arrayidx = getelementptr inbounds [8 x ptr], ptr addrspace(5) %data, i64 0, i64 %x
94+
%l = load ptr, ptr addrspace(5) %arrayidx, align 8, !nonnull !5
95+
ret ptr %l
96+
}
97+
98+
!5 = !{}
99+
100+
; CHECK: [[NONNULL]] = !{}
101+
102+
; Verify invariant.load metadata on a cloned load is preserved. OK
103+
define i32 @copy_invariant_load_metadata_after_memcpy(i64 %x) {
104+
; CHECK-LABEL: define i32 @copy_invariant_load_metadata_after_memcpy(
105+
; CHECK-SAME: i64 [[X:%.*]]) {
106+
; CHECK-NEXT: entry:
107+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr addrspace(2) @test.data, i64 [[X]]
108+
; CHECK-NEXT: [[L:%.*]] = load i32, ptr addrspace(2) [[ARRAYIDX]], align 4, !invariant.load [[INVLOAD:![0-9]+]]
109+
; CHECK-NEXT: ret i32 [[L]]
110+
;
111+
entry:
112+
%data = alloca [8 x i32], align 4, addrspace(5)
113+
call void @llvm.memcpy.p5.p2.i64(ptr addrspace(5) align 4 %data, ptr addrspace(2) align 4 @test.data, i64 32, i1 false)
114+
%arrayidx = getelementptr inbounds [8 x i32], ptr addrspace(5) %data, i64 0, i64 %x
115+
%l = load i32, ptr addrspace(5) %arrayidx, align 4, !invariant.load !5
116+
ret i32 %l
117+
}
118+
119+
; CHECK: [[INVLOAD]] = !{}
120+
121+
; Verify alias.scope and noalias metadata on a cloned load are preserved. OK
122+
define i32 @copy_aliasscope_noalias_metadata_after_memcpy(i64 %x) {
123+
; CHECK-LABEL: define i32 @copy_aliasscope_noalias_metadata_after_memcpy(
124+
; CHECK-SAME: i64 [[X:%.*]]) {
125+
; CHECK-NEXT: entry:
126+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr addrspace(2) @test.data, i64 [[X]]
127+
; CHECK-NEXT: [[L:%.*]] = load i32, ptr addrspace(2) [[ARRAYIDX]], align 4, !alias.scope [[ALIASSET:![0-9]+]], !noalias [[ALIASSET]]
128+
; CHECK-NEXT: ret i32 [[L]]
129+
;
130+
entry:
131+
%data = alloca [8 x i32], align 4, addrspace(5)
132+
call void @llvm.memcpy.p5.p2.i64(ptr addrspace(5) align 4 %data, ptr addrspace(2) align 4 @test.data, i64 32, i1 false)
133+
%arrayidx = getelementptr inbounds [8 x i32], ptr addrspace(5) %data, i64 0, i64 %x
134+
%l = load i32, ptr addrspace(5) %arrayidx, align 4, !alias.scope !6, !noalias !6
135+
ret i32 %l
136+
}
137+
138+
; Verify nontemporal metadata on a cloned load is preserved.OK
139+
define i32 @copy_nontemporal_metadata_after_memcpy(i64 %x) {
140+
; CHECK-LABEL: define i32 @copy_nontemporal_metadata_after_memcpy(
141+
; CHECK-SAME: i64 [[X:%.*]]) {
142+
; CHECK-NEXT: entry:
143+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr addrspace(2) @test.data, i64 [[X]]
144+
; CHECK-NEXT: [[L:%.*]] = load i32, ptr addrspace(2) [[ARRAYIDX]], align 4, !nontemporal [[NT:![0-9]+]]
145+
; CHECK-NEXT: ret i32 [[L]]
146+
;
147+
entry:
148+
%data = alloca [8 x i32], align 4, addrspace(5)
149+
call void @llvm.memcpy.p5.p2.i64(ptr addrspace(5) align 4 %data, ptr addrspace(2) align 4 @test.data, i64 32, i1 false)
150+
%arrayidx = getelementptr inbounds [8 x i32], ptr addrspace(5) %data, i64 0, i64 %x
151+
%l = load i32, ptr addrspace(5) %arrayidx, align 4, !nontemporal !9
152+
ret i32 %l
153+
}
154+
155+
; Verify access group metadata on a cloned load is preserved. OK
156+
define i32 @copy_access_group_metadata_after_memcpy(i64 %x) {
157+
; CHECK-LABEL: define i32 @copy_access_group_metadata_after_memcpy(
158+
; CHECK-SAME: i64 [[X:%.*]]) {
159+
; CHECK-NEXT: entry:
160+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr addrspace(2) @test.data, i64 [[X]]
161+
; CHECK-NEXT: [[L:%.*]] = load i32, ptr addrspace(2) [[ARRAYIDX]], align 4, !llvm.access.group [[ACCGRP:![0-9]+]]
162+
; CHECK-NEXT: ret i32 [[L]]
163+
;
164+
entry:
165+
%data = alloca [8 x i32], align 4, addrspace(5)
166+
call void @llvm.memcpy.p5.p2.i64(ptr addrspace(5) align 4 %data, ptr addrspace(2) align 4 @test.data, i64 32, i1 false)
167+
%arrayidx = getelementptr inbounds [8 x i32], ptr addrspace(5) %data, i64 0, i64 %x
168+
%l = load i32, ptr addrspace(5) %arrayidx, align 4, !llvm.access.group !10
169+
ret i32 %l
170+
}
171+
172+
; Verify noalias.addrspace metadata on a cloned load is preserved.
173+
define i32 @copy_noalias_addrspace_metadata_after_memcpy(i64 %x) {
174+
; CHECK-LABEL: define i32 @copy_noalias_addrspace_metadata_after_memcpy(
175+
; CHECK-SAME: i64 [[X:%.*]]) {
176+
; CHECK-NEXT: entry:
177+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr addrspace(2) @test.data, i64 [[X]]
178+
; CHECK-NEXT: [[L:%.*]] = load i32, ptr addrspace(2) [[ARRAYIDX]], align 4, !noalias.addrspace [[NAAS:![0-9]+]]
179+
; CHECK-NEXT: ret i32 [[L]]
180+
;
181+
entry:
182+
%data = alloca [8 x i32], align 4, addrspace(5)
183+
call void @llvm.memcpy.p5.p2.i64(ptr addrspace(5) align 4 %data, ptr addrspace(2) align 4 @test.data, i64 32, i1 false)
184+
%arrayidx = getelementptr inbounds [8 x i32], ptr addrspace(5) %data, i64 0, i64 %x
185+
%l = load i32, ptr addrspace(5) %arrayidx, align 4, !noalias.addrspace !12
186+
ret i32 %l
187+
}
188+
189+
; Verify llvm.mem.parallel_loop_access metadata on a cloned load is preserved. OK
190+
define i32 @copy_mem_parallel_loop_access_metadata_after_memcpy(i64 %x) {
191+
; CHECK-LABEL: define i32 @copy_mem_parallel_loop_access_metadata_after_memcpy(
192+
; CHECK-SAME: i64 [[X:%.*]]) {
193+
; CHECK-NEXT: entry:
194+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr addrspace(2) @test.data, i64 [[X]]
195+
; CHECK-NEXT: [[L:%.*]] = load i32, ptr addrspace(2) [[ARRAYIDX]], align 4, !llvm.mem.parallel_loop_access [[MPLA:![0-9]+]]
196+
; CHECK-NEXT: ret i32 [[L]]
197+
;
198+
entry:
199+
%data = alloca [8 x i32], align 4, addrspace(5)
200+
call void @llvm.memcpy.p5.p2.i64(ptr addrspace(5) align 4 %data, ptr addrspace(2) align 4 @test.data, i64 32, i1 false)
201+
%arrayidx = getelementptr inbounds [8 x i32], ptr addrspace(5) %data, i64 0, i64 %x
202+
%l = load i32, ptr addrspace(5) %arrayidx, align 4, !llvm.mem.parallel_loop_access !13
203+
ret i32 %l
204+
}
205+
206+
!6 = !{!7}
207+
!7 = distinct !{!7, !8}
208+
!8 = distinct !{!8}
209+
!9 = !{i32 1}
210+
!10 = distinct !{}
211+
!12 = !{i32 5, i32 6}
212+
!13 = !{!14}
213+
!14 = distinct !{}
214+
215+
; CHECK: [[ALIASSET]] = !{[[ALIASSETNODE:![0-9]+]]}
216+
; CHECK: [[ALIASSETNODE]] = distinct !{[[ALIASSETNODE]], [[ALIASSETNODE2:![0-9]+]]}
217+
; CHECK: [[ALIASSETNODE2]] = distinct !{[[ALIASSETNODE2]]}
218+
; CHECK: [[NT]] = !{i32 1}
219+
; CHECK: [[ACCGRP]] = distinct !{}
220+
; CHECK: [[NOUNDEF]] = !{}
221+
; CHECK: [[NAAS]] = !{i32 5, i32 6}
222+
; CHECK: [[MPLA]] = !{[[MPLALOOP:![0-9]+]]}
223+
; CHECK: [[MPLALOOP]] = distinct !{}

llvm/test/Transforms/LoadStoreVectorizer/AMDGPU/copy-metadata-load-store.ll

Lines changed: 83 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -36,65 +36,97 @@ entry:
3636
ret void
3737
}
3838

39-
; Check that MD_nonnull on pointer loads is transformed to an integer !range
40-
; via copyMetadataForAccess during normalization.
41-
define void @lsv_copy_load_nonnull_to_range(ptr %p) {
42-
; CHECK-LABEL: define void @lsv_copy_load_nonnull_to_range(
39+
; Copy alias.scope and noalias metadata on vectorized stores.
40+
define void @lsv_copy_store_alias_metadata(ptr %p) {
41+
; CHECK-LABEL: define void @lsv_copy_store_alias_metadata(
4342
; CHECK-SAME: ptr [[P:%.*]]) {
4443
; CHECK-NEXT: [[ENTRY:.*:]]
45-
; CHECK-NEXT: [[VEC:%.*]] = load <2 x i64>, ptr [[P]], align 8
46-
; CHECK-NEXT: [[LD01:%.*]] = extractelement <2 x i64> [[VEC]], i32 0
47-
; CHECK-NEXT: [[TMP1:%.*]] = inttoptr i64 [[LD01]] to ptr
48-
; CHECK-NEXT: [[LD12:%.*]] = extractelement <2 x i64> [[VEC]], i32 1
44+
; CHECK-NEXT: store <2 x i32> <i32 1, i32 bitcast (<2 x i16> <i16 2, i16 3> to i32)>, ptr [[P]], align 4, !alias.scope [[META5:![0-9]+]], !noalias [[META5]]
4945
; CHECK-NEXT: ret void
5046
;
5147
entry:
52-
%p1 = getelementptr i64, ptr %p, i64 1
53-
%ld0 = load ptr, ptr %p, align 8, !nonnull !6
54-
%ld1 = load i64, ptr %p1, align 8
48+
%p1 = getelementptr i32, ptr %p, i64 1
49+
store i32 1, ptr %p, align 4, !alias.scope !11, !noalias !11
50+
store <2 x i16> <i16 2, i16 3>, ptr %p1, align 4, !alias.scope !11, !noalias !11
51+
ret void
52+
}
53+
54+
; Copy access group metadata on vectorized stores.
55+
define void @lsv_copy_store_access_group(ptr %p) {
56+
; CHECK-LABEL: define void @lsv_copy_store_access_group(
57+
; CHECK-SAME: ptr [[P:%.*]]) {
58+
; CHECK-NEXT: [[ENTRY:.*:]]
59+
; CHECK-NEXT: store <2 x i32> <i32 9, i32 bitcast (<2 x i16> <i16 8, i16 7> to i32)>, ptr [[P]], align 4
60+
; CHECK-NEXT: ret void
61+
;
62+
entry:
63+
%p1 = getelementptr i32, ptr %p, i64 1
64+
store i32 9, ptr %p, align 4, !llvm.access.group !14
65+
store <2 x i16> <i16 8, i16 7>, ptr %p1, align 4, !llvm.access.group !14
5566
ret void
5667
}
5768

58-
; Check that MD_dereferenceable_or_null is not propagated when the new type is
59-
; not a pointer after normalization (as per copyMetadataForAccess semantics).
60-
define void @lsv_copy_load_deref_or_null(ptr %p) {
61-
; CHECK-LABEL: define void @lsv_copy_load_deref_or_null(
69+
; Copy noundef metadata on vectorized stores.
70+
define void @lsv_copy_store_noundef(ptr %p) {
71+
; CHECK-LABEL: define void @lsv_copy_store_noundef(
6272
; CHECK-SAME: ptr [[P:%.*]]) {
6373
; CHECK-NEXT: [[ENTRY:.*:]]
64-
; CHECK-NEXT: [[VEC:%.*]] = load <2 x i64>, ptr [[P]], align 8
65-
; CHECK-NEXT: [[LD01:%.*]] = extractelement <2 x i64> [[VEC]], i32 0
66-
; CHECK-NEXT: [[TMP1:%.*]] = inttoptr i64 [[LD01]] to ptr
67-
; CHECK-NEXT: [[LD12:%.*]] = extractelement <2 x i64> [[VEC]], i32 1
74+
; CHECK-NEXT: store <2 x i32> <i32 42, i32 bitcast (<2 x i16> <i16 6, i16 5> to i32)>, ptr [[P]], align 4
6875
; CHECK-NEXT: ret void
6976
;
7077
entry:
71-
%p1 = getelementptr i64, ptr %p, i64 1
72-
%ld0 = load ptr, ptr %p, align 8, !dereferenceable_or_null !7
73-
%ld1 = load i64, ptr %p1, align 8
78+
%p1 = getelementptr i32, ptr %p, i64 1
79+
store i32 42, ptr %p, align 4, !noundef !15
80+
store <2 x i16> <i16 6, i16 5>, ptr %p1, align 4, !noundef !15
7481
ret void
7582
}
7683

77-
; Stores do not accept !dereferenceable_or_null metadata; ensure vectorization
78-
; still succeeds on a mixed chain without such metadata on stores.
79-
define void @lsv_copy_store_chain(ptr %p, ptr %q) {
80-
; CHECK-LABEL: define void @lsv_copy_store_chain(
81-
; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
84+
; Copy noalias.addrspace metadata on vectorized stores.
85+
define void @lsv_copy_store_noalias_addrspace(ptr %p) {
86+
; CHECK-LABEL: define void @lsv_copy_store_noalias_addrspace(
87+
; CHECK-SAME: ptr [[P:%.*]]) {
8288
; CHECK-NEXT: [[ENTRY:.*:]]
83-
; CHECK-NEXT: [[P1:%.*]] = getelementptr i64, ptr [[P]], i64 1
84-
; CHECK-NEXT: [[Q1:%.*]] = getelementptr i64, ptr [[Q]], i64 1
85-
; CHECK-NEXT: [[V:%.*]] = load ptr, ptr [[P]], align 8
86-
; CHECK-NEXT: store ptr [[V]], ptr [[Q]], align 8
87-
; CHECK-NEXT: [[W:%.*]] = load i64, ptr [[P1]], align 8
88-
; CHECK-NEXT: store i64 [[W]], ptr [[Q1]], align 8
89+
; CHECK-NEXT: store <2 x i32> <i32 11, i32 bitcast (<2 x i16> <i16 10, i16 9> to i32)>, ptr [[P]], align 4
8990
; CHECK-NEXT: ret void
9091
;
9192
entry:
92-
%p1 = getelementptr i64, ptr %p, i64 1
93-
%q1 = getelementptr i64, ptr %q, i64 1
94-
%v = load ptr, ptr %p, align 8
95-
store ptr %v, ptr %q, align 8
96-
%w = load i64, ptr %p1, align 8
97-
store i64 %w, ptr %q1, align 8
93+
%p1 = getelementptr i32, ptr %p, i64 1
94+
store i32 11, ptr %p, align 4, !noalias.addrspace !16
95+
store <2 x i16> <i16 10, i16 9>, ptr %p1, align 4, !noalias.addrspace !16
96+
ret void
97+
}
98+
99+
; Copy llvm.mem.parallel_loop_access metadata on vectorized stores.
100+
define void @lsv_copy_store_mem_parallel_loop_access(ptr %p) {
101+
; CHECK-LABEL: define void @lsv_copy_store_mem_parallel_loop_access(
102+
; CHECK-SAME: ptr [[P:%.*]]) {
103+
; CHECK-NEXT: [[ENTRY:.*:]]
104+
; CHECK-NEXT: store <2 x i32> <i32 13, i32 bitcast (<2 x i16> <i16 12, i16 11> to i32)>, ptr [[P]], align 4
105+
; CHECK-NEXT: ret void
106+
;
107+
entry:
108+
%p1 = getelementptr i32, ptr %p, i64 1
109+
store i32 13, ptr %p, align 4, !llvm.mem.parallel_loop_access !17
110+
store <2 x i16> <i16 12, i16 11>, ptr %p1, align 4, !llvm.mem.parallel_loop_access !17
111+
ret void
112+
}
113+
114+
; Normalized type is not a pointer in the following test, avoid copying
115+
; dereferenceable_or_null metadata.
116+
define void @lsv_no_copy_deref_or_null(ptr %p) {
117+
; CHECK-LABEL: define void @lsv_no_copy_deref_or_null(
118+
; CHECK-SAME: ptr [[P:%.*]]) {
119+
; CHECK-NEXT: [[ENTRY:.*:]]
120+
; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[P]], align 8
121+
; CHECK-NEXT: [[LD0_MUT1:%.*]] = extractelement <2 x i64> [[TMP0]], i32 0
122+
; CHECK-NEXT: [[LD12:%.*]] = extractelement <2 x i64> [[TMP0]], i32 1
123+
; CHECK-NEXT: [[LD0_MUT_BC:%.*]] = inttoptr i64 [[LD0_MUT1]] to ptr
124+
; CHECK-NEXT: ret void
125+
;
126+
entry:
127+
%p1 = getelementptr i32, ptr %p, i64 1
128+
%ld0 = load ptr, ptr %p, align 4, !dereferenceable_or_null !7
129+
%ld1 = load i64, ptr %p1, align 4
98130
ret void
99131
}
100132

@@ -104,6 +136,15 @@ entry:
104136
!5 = !{i32 1}
105137
!6 = !{}
106138
!7 = !{i64 8}
139+
!8 = !{i64 1, i64 256}
140+
!11 = !{!12}
141+
!12 = distinct !{!12, !13}
142+
!13 = distinct !{!13}
143+
!14 = distinct !{}
144+
!15 = !{}
145+
!16 = !{i32 5, i32 6}
146+
!17 = !{!18}
147+
!18 = distinct !{}
107148
attributes #0 = { nounwind }
108149
attributes #1 = { nounwind readnone }
109150
;.
@@ -112,4 +153,7 @@ attributes #1 = { nounwind readnone }
112153
; CHECK: [[META2]] = !{!"Simple C/C++ TBAA"}
113154
; CHECK: [[META3]] = !{}
114155
; CHECK: [[META4]] = !{i32 1}
156+
; CHECK: [[META5]] = !{[[META6:![0-9]+]]}
157+
; CHECK: [[META6]] = distinct !{[[META6]], [[META7:![0-9]+]]}
158+
; CHECK: [[META7]] = distinct !{[[META7]]}
115159
;.

0 commit comments

Comments
 (0)