1 ; RUN: opt < %s -passes=memprof -memprof-use-callbacks -S \
2 ; RUN: | FileCheck %s -check-prefix=LOAD -check-prefix=STORE -check-prefix=ALL
3 ; RUN: opt < %s -passes=memprof -memprof-use-callbacks -memprof-instrument-reads=0 -S \
4 ; RUN: | FileCheck %s -check-prefix=NOLOAD -check-prefix=STORE -check-prefix=ALL
5 ; RUN: opt < %s -passes=memprof -memprof-use-callbacks -memprof-instrument-writes=0 -S \
6 ; RUN: | FileCheck %s -check-prefix=LOAD -check-prefix=NOSTORE -check-prefix=ALL
7 ; RUN: opt < %s -passes=memprof -memprof-use-callbacks -memprof-instrument-reads=0 -memprof-instrument-writes=0 -S \
8 ; RUN: | FileCheck %s -check-prefix=NOLOAD -check-prefix=NOSTORE -check-prefix=ALL
9 ; Support memory profiling instrumentation for constant-mask llvm.masked.{load,store}
11 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
13 @v4f32 = global ptr zeroinitializer, align 8
14 @v8i32 = global ptr zeroinitializer, align 8
15 @v4i64 = global ptr zeroinitializer, align 8
17 ;;;;;;;;;;;;;;;; STORE
18 declare void @llvm.masked.store.v4f32.p0(<4 x float>, ptr, i32, <4 x i1>) argmemonly nounwind
19 declare void @llvm.masked.store.v8i32.p0(<8 x i32>, ptr, i32, <8 x i1>) argmemonly nounwind
20 declare void @llvm.masked.store.v4p0.p0(<4 x ptr>, ptr, i32, <4 x i1>) argmemonly nounwind
22 define void @store.v4f32.1110(<4 x float> %arg) {
23 ; ALL-LABEL: @store.v4f32.1110
24 %p = load ptr, ptr @v4f32, align 8
25 ; NOSTORE-NOT: call void @__memprof_store
26 ; STORE: [[GEP0:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 0
27 ; STORE: [[PGEP0:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP0]] to i64
28 ; STORE: call void @__memprof_store(i64 [[PGEP0]])
29 ; STORE: [[GEP1:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 1
30 ; STORE: [[PGEP1:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP1]] to i64
31 ; STORE: call void @__memprof_store(i64 [[PGEP1]])
32 ; STORE: [[GEP2:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 2
33 ; STORE: [[PGEP2:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP2]] to i64
34 ; STORE: call void @__memprof_store(i64 [[PGEP2]])
35 ; STORE: tail call void @llvm.masked.store.v4f32.p0(<4 x float> %arg, ptr %p, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 false>)
36 tail call void @llvm.masked.store.v4f32.p0(<4 x float> %arg, ptr %p, i32 4, <4 x i1> <i1 true, i1 true, i1 true, i1 false>)
40 define void @store.v8i32.10010110(<8 x i32> %arg) {
41 ; ALL-LABEL: @store.v8i32.10010110
42 %p = load ptr, ptr @v8i32, align 8
43 ; NOSTORE-NOT: call void @__memprof_store
44 ; STORE: [[GEP0:%[0-9A-Za-z]+]] = getelementptr <8 x i32>, ptr %p, i64 0, i64 0
45 ; STORE: [[PGEP0:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP0]] to i64
46 ; STORE: call void @__memprof_store(i64 [[PGEP0]])
47 ; STORE: [[GEP3:%[0-9A-Za-z]+]] = getelementptr <8 x i32>, ptr %p, i64 0, i64 3
48 ; STORE: [[PGEP3:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP3]] to i64
49 ; STORE: call void @__memprof_store(i64 [[PGEP3]])
50 ; STORE: [[GEP5:%[0-9A-Za-z]+]] = getelementptr <8 x i32>, ptr %p, i64 0, i64 5
51 ; STORE: [[PGEP5:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP5]] to i64
52 ; STORE: call void @__memprof_store(i64 [[PGEP5]])
53 ; STORE: [[GEP6:%[0-9A-Za-z]+]] = getelementptr <8 x i32>, ptr %p, i64 0, i64 6
54 ; STORE: [[PGEP6:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP6]] to i64
55 ; STORE: call void @__memprof_store(i64 [[PGEP6]])
56 ; STORE: tail call void @llvm.masked.store.v8i32.p0(<8 x i32> %arg, ptr %p, i32 8, <8 x i1> <i1 true, i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 false>)
57 tail call void @llvm.masked.store.v8i32.p0(<8 x i32> %arg, ptr %p, i32 8, <8 x i1> <i1 true, i1 false, i1 false, i1 true, i1 false, i1 true, i1 true, i1 false>)
61 define void @store.v4i64.0001(<4 x ptr> %arg) {
62 ; ALL-LABEL: @store.v4i64.0001
63 %p = load ptr, ptr @v4i64, align 8
64 ; NOSTORE-NOT: call void @__memprof_store
65 ; STORE: [[GEP3:%[0-9A-Za-z]+]] = getelementptr <4 x ptr>, ptr %p, i64 0, i64 3
66 ; STORE: [[PGEP3:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP3]] to i64
67 ; STORE: call void @__memprof_store(i64 [[PGEP3]])
68 ; STORE: tail call void @llvm.masked.store.v4p0.p0(<4 x ptr> %arg, ptr %p, i32 8, <4 x i1> <i1 false, i1 false, i1 false, i1 true>)
69 tail call void @llvm.masked.store.v4p0.p0(<4 x ptr> %arg, ptr %p, i32 8, <4 x i1> <i1 false, i1 false, i1 false, i1 true>)
73 define void @store.v4f32.variable(<4 x float> %arg, <4 x i1> %mask) {
74 ; ALL-LABEL: @store.v4f32.variable
75 %p = load ptr, ptr @v4f32, align 8
76 ; STORE: [[MASK0:%[0-9A-Za-z]+]] = extractelement <4 x i1> %mask, i64 0
77 ; STORE: br i1 [[MASK0]], label %[[THEN0:[0-9A-Za-z]+]], label %[[AFTER0:[0-9A-Za-z]+]]
79 ; STORE: [[GEP0:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 0
80 ; STORE: [[PGEP0:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP0]] to i64
81 ; STORE: call void @__memprof_store(i64 [[PGEP0]])
82 ; STORE: br label %[[AFTER0]]
85 ; STORE: [[MASK1:%[0-9A-Za-z]+]] = extractelement <4 x i1> %mask, i64 1
86 ; STORE: br i1 [[MASK1]], label %[[THEN1:[0-9A-Za-z]+]], label %[[AFTER1:[0-9A-Za-z]+]]
88 ; STORE: [[GEP1:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 1
89 ; STORE: [[PGEP1:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP1]] to i64
90 ; STORE: call void @__memprof_store(i64 [[PGEP1]])
91 ; STORE: br label %[[AFTER1]]
94 ; STORE: [[MASK2:%[0-9A-Za-z]+]] = extractelement <4 x i1> %mask, i64 2
95 ; STORE: br i1 [[MASK2]], label %[[THEN2:[0-9A-Za-z]+]], label %[[AFTER2:[0-9A-Za-z]+]]
97 ; STORE: [[GEP2:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 2
98 ; STORE: [[PGEP2:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP2]] to i64
99 ; STORE: call void @__memprof_store(i64 [[PGEP2]])
100 ; STORE: br label %[[AFTER2]]
103 ; STORE: [[MASK3:%[0-9A-Za-z]+]] = extractelement <4 x i1> %mask, i64 3
104 ; STORE: br i1 [[MASK3]], label %[[THEN3:[0-9A-Za-z]+]], label %[[AFTER3:[0-9A-Za-z]+]]
106 ; STORE: [[GEP3:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 3
107 ; STORE: [[PGEP3:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP3]] to i64
108 ; STORE: call void @__memprof_store(i64 [[PGEP3]])
109 ; STORE: br label %[[AFTER3]]
112 ; STORE: tail call void @llvm.masked.store.v4f32.p0(<4 x float> %arg, ptr %p, i32 4, <4 x i1> %mask)
113 tail call void @llvm.masked.store.v4f32.p0(<4 x float> %arg, ptr %p, i32 4, <4 x i1> %mask)
117 ;; Store using two masked.stores, which should instrument them both.
118 define void @store.v4f32.1010.split(<4 x float> %arg) {
119 ; BOTH-LABEL: @store.v4f32.1010.split
120 %p = load ptr, ptr @v4f32, align 8
121 ; STORE: [[GEP0:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 0
122 ; STORE: [[PGEP0:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP0]] to i64
123 ; STORE: call void @__memprof_store(i64 [[PGEP0]])
124 ; STORE: tail call void @llvm.masked.store.v4f32.p0(<4 x float> %arg, ptr %p, i32 4, <4 x i1> <i1 true, i1 false, i1 false, i1 false>)
125 tail call void @llvm.masked.store.v4f32.p0(<4 x float> %arg, ptr %p, i32 4, <4 x i1> <i1 true, i1 false, i1 false, i1 false>)
126 ; STORE: [[GEP1:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 2
127 ; STORE: [[PGEP1:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP1]] to i64
128 ; STORE: call void @__memprof_store(i64 [[PGEP1]])
129 ; STORE: tail call void @llvm.masked.store.v4f32.p0(<4 x float> %arg, ptr %p, i32 4, <4 x i1> <i1 false, i1 false, i1 true, i1 false>)
130 tail call void @llvm.masked.store.v4f32.p0(<4 x float> %arg, ptr %p, i32 4, <4 x i1> <i1 false, i1 false, i1 true, i1 false>)
134 ;;;;;;;;;;;;;;;; LOAD
135 declare <4 x float> @llvm.masked.load.v4f32.p0(ptr, i32, <4 x i1>, <4 x float>) argmemonly nounwind
136 declare <8 x i32> @llvm.masked.load.v8i32.p0(ptr, i32, <8 x i1>, <8 x i32>) argmemonly nounwind
137 declare <4 x ptr> @llvm.masked.load.v4p0.p0(ptr, i32, <4 x i1>, <4 x ptr>) argmemonly nounwind
139 define <8 x i32> @load.v8i32.11100001(<8 x i32> %arg) {
140 ; ALL-LABEL: @load.v8i32.11100001
141 %p = load ptr, ptr @v8i32, align 8
142 ; NOLOAD-NOT: call void @__memprof_load
143 ; LOAD: [[GEP0:%[0-9A-Za-z]+]] = getelementptr <8 x i32>, ptr %p, i64 0, i64 0
144 ; LOAD: [[PGEP0:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP0]] to i64
145 ; LOAD: call void @__memprof_load(i64 [[PGEP0]])
146 ; LOAD: [[GEP1:%[0-9A-Za-z]+]] = getelementptr <8 x i32>, ptr %p, i64 0, i64 1
147 ; LOAD: [[PGEP1:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP1]] to i64
148 ; LOAD: call void @__memprof_load(i64 [[PGEP1]])
149 ; LOAD: [[GEP2:%[0-9A-Za-z]+]] = getelementptr <8 x i32>, ptr %p, i64 0, i64 2
150 ; LOAD: [[PGEP2:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP2]] to i64
151 ; LOAD: call void @__memprof_load(i64 [[PGEP2]])
152 ; LOAD: [[GEP7:%[0-9A-Za-z]+]] = getelementptr <8 x i32>, ptr %p, i64 0, i64 7
153 ; LOAD: [[PGEP7:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP7]] to i64
154 ; LOAD: call void @__memprof_load(i64 [[PGEP7]])
155 ; LOAD: tail call <8 x i32> @llvm.masked.load.v8i32.p0(ptr %p, i32 8, <8 x i1> <i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 true>, <8 x i32> %arg)
156 %res = tail call <8 x i32> @llvm.masked.load.v8i32.p0(ptr %p, i32 8, <8 x i1> <i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 true>, <8 x i32> %arg)
160 define <4 x float> @load.v4f32.1001(<4 x float> %arg) {
161 ; ALL-LABEL: @load.v4f32.1001
162 %p = load ptr, ptr @v4f32, align 8
163 ; NOLOAD-NOT: call void @__memprof_load
164 ; LOAD: [[GEP0:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 0
165 ; LOAD: [[PGEP0:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP0]] to i64
166 ; LOAD: call void @__memprof_load(i64 [[PGEP0]])
167 ; LOAD: [[GEP3:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 3
168 ; LOAD: [[PGEP3:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP3]] to i64
169 ; LOAD: call void @__memprof_load(i64 [[PGEP3]])
170 ; LOAD: tail call <4 x float> @llvm.masked.load.v4f32.p0(ptr %p, i32 4, <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x float> %arg)
171 %res = tail call <4 x float> @llvm.masked.load.v4f32.p0(ptr %p, i32 4, <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x float> %arg)
175 define <4 x ptr> @load.v4i64.0001(<4 x ptr> %arg) {
176 ; ALL-LABEL: @load.v4i64.0001
177 %p = load ptr, ptr @v4i64, align 8
178 ; NOLOAD-NOT: call void @__memprof_load
179 ; LOAD: [[GEP3:%[0-9A-Za-z]+]] = getelementptr <4 x ptr>, ptr %p, i64 0, i64 3
180 ; LOAD: [[PGEP3:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP3]] to i64
181 ; LOAD: call void @__memprof_load(i64 [[PGEP3]])
182 ; LOAD: tail call <4 x ptr> @llvm.masked.load.v4p0.p0(ptr %p, i32 8, <4 x i1> <i1 false, i1 false, i1 false, i1 true>, <4 x ptr> %arg)
183 %res = tail call <4 x ptr> @llvm.masked.load.v4p0.p0(ptr %p, i32 8, <4 x i1> <i1 false, i1 false, i1 false, i1 true>, <4 x ptr> %arg)
187 define <4 x float> @load.v4f32.variable(<4 x float> %arg, <4 x i1> %mask) {
188 ; ALL-LABEL: @load.v4f32.variable
189 %p = load ptr, ptr @v4f32, align 8
190 ; LOAD: [[MASK0:%[0-9A-Za-z]+]] = extractelement <4 x i1> %mask, i64 0
191 ; LOAD: br i1 [[MASK0]], label %[[THEN0:[0-9A-Za-z]+]], label %[[AFTER0:[0-9A-Za-z]+]]
193 ; LOAD: [[GEP0:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 0
194 ; LOAD: [[PGEP0:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP0]] to i64
195 ; LOAD: call void @__memprof_load(i64 [[PGEP0]])
196 ; LOAD: br label %[[AFTER0]]
199 ; LOAD: [[MASK1:%[0-9A-Za-z]+]] = extractelement <4 x i1> %mask, i64 1
200 ; LOAD: br i1 [[MASK1]], label %[[THEN1:[0-9A-Za-z]+]], label %[[AFTER1:[0-9A-Za-z]+]]
202 ; LOAD: [[GEP1:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 1
203 ; LOAD: [[PGEP1:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP1]] to i64
204 ; LOAD: call void @__memprof_load(i64 [[PGEP1]])
205 ; LOAD: br label %[[AFTER1]]
208 ; LOAD: [[MASK2:%[0-9A-Za-z]+]] = extractelement <4 x i1> %mask, i64 2
209 ; LOAD: br i1 [[MASK2]], label %[[THEN2:[0-9A-Za-z]+]], label %[[AFTER2:[0-9A-Za-z]+]]
211 ; LOAD: [[GEP2:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 2
212 ; LOAD: [[PGEP2:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP2]] to i64
213 ; LOAD: call void @__memprof_load(i64 [[PGEP2]])
214 ; LOAD: br label %[[AFTER2]]
217 ; LOAD: [[MASK3:%[0-9A-Za-z]+]] = extractelement <4 x i1> %mask, i64 3
218 ; LOAD: br i1 [[MASK3]], label %[[THEN3:[0-9A-Za-z]+]], label %[[AFTER3:[0-9A-Za-z]+]]
220 ; LOAD: [[GEP3:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 3
221 ; LOAD: [[PGEP3:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP3]] to i64
222 ; LOAD: call void @__memprof_load(i64 [[PGEP3]])
223 ; LOAD: br label %[[AFTER3]]
226 ; LOAD: tail call <4 x float> @llvm.masked.load.v4f32.p0(ptr %p, i32 4, <4 x i1> %mask, <4 x float> %arg)
227 %res = tail call <4 x float> @llvm.masked.load.v4f32.p0(ptr %p, i32 4, <4 x i1> %mask, <4 x float> %arg)
231 ;; Load using two masked.loads, which should instrument them both.
232 define <4 x float> @load.v4f32.1001.split(<4 x float> %arg) {
233 ; BOTH-LABEL: @load.v4f32.1001
234 %p = load ptr, ptr @v4f32, align 8
235 ; LOAD: [[GEP0:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 0
236 ; LOAD: [[PGEP0:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP0]] to i64
237 ; LOAD: call void @__memprof_load(i64 [[PGEP0]])
238 ; LOAD: %res = tail call <4 x float> @llvm.masked.load.v4f32.p0(ptr %p, i32 4, <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x float> %arg)
239 %res = tail call <4 x float> @llvm.masked.load.v4f32.p0(ptr %p, i32 4, <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x float> %arg)
240 ; LOAD: [[GEP3:%[0-9A-Za-z]+]] = getelementptr <4 x float>, ptr %p, i64 0, i64 3
241 ; LOAD: [[PGEP3:%[0-9A-Za-z]+]] = ptrtoint ptr [[GEP3]] to i64
242 ; LOAD: call void @__memprof_load(i64 [[PGEP3]])
243 ; LOAD: tail call <4 x float> @llvm.masked.load.v4f32.p0(ptr %p, i32 4, <4 x i1> <i1 false, i1 false, i1 false, i1 true>, <4 x float> %res)
244 %res2 = tail call <4 x float> @llvm.masked.load.v4f32.p0(ptr %p, i32 4, <4 x i1> <i1 false, i1 false, i1 false, i1 true>, <4 x float> %res)
245 ret <4 x float> %res2