llvm.org GIT mirror llvm / 4d88c3e
Dereferenceable, dereferenceable_or_null metadata for loads Summary: Introduce dereferenceable, dereferenceable_or_null metadata for loads with the same semantic as corresponding attributes. This patch depends on http://reviews.llvm.org/D9253 Patch by Artur Pilipenko! Reviewers: hfinkel, sanjoy, reames Reviewed By: sanjoy, reames Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D9365 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237720 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjoy Das 4 years ago
6 changed file(s) with 215 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
56575657
56585658 ::
56595659
5660 = load [volatile] , * [, align ][, !nontemporal !][, !invariant.load !][, !nonnull !]
5660 = load [volatile] , * [, align ][, !nontemporal !][, !invariant.load !][, !nonnull !][, !dereferenceable !][, !dereferenceable_or_null !]
56615661 = load atomic [volatile] * [singlethread] , align
56625662 ! = !{ i32 1 }
56635663
57205720 instruction tells the optimizer that the value loaded is known to
57215721 never be null. This is analogous to the ''nonnull'' attribute
57225722 on parameters and return values. This metadata can only be applied
5723 to loads of a pointer type.
5724
5725 The optional ``!dereferenceable`` metadata must reference a single
5726 metadata name ```` corresponding to a metadata node with one ``i64``
5727 entry. The existence of the ``!dereferenceable`` metadata on the instruction
5728 tells the optimizer that the value loaded is known to be dereferenceable.
5729 The number of bytes known to be dereferenceable is specified by the integer
5730 value in the metadata node. This is analogous to the ''dereferenceable''
5731 attribute on parameters and return values. This metadata can only be applied
5732 to loads of a pointer type.
5733
5734 The optional ``!dereferenceable_or_null`` metadata must reference a single
5735 metadata name ```` corresponding to a metadata node with one ``i64``
5736 entry. The existence of the ``!dereferenceable_or_null`` metadata on the
5737 instruction tells the optimizer that the value loaded is known to be either
5738 dereferenceable or null.
5739 The number of bytes known to be dereferenceable is specified by the integer
5740 value in the metadata node. This is analogous to the ''dereferenceable_or_null''
5741 attribute on parameters and return values. This metadata can only be applied
57235742 to loads of a pointer type.
57245743
57255744 Semantics:
5757 MD_noalias = 8, // "noalias",
5858 MD_nontemporal = 9, // "nontemporal"
5959 MD_mem_parallel_loop_access = 10, // "llvm.mem.parallel_loop_access"
60 MD_nonnull = 11 // "nonnull"
60 MD_nonnull = 11, // "nonnull"
61 MD_dereferenceable = 12, // "dereferenceable"
62 MD_dereferenceable_or_null = 13 // "dereferenceable_or_null"
6163 };
6264
6365 /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
28842884 DerefBytes = CS.getDereferenceableOrNullBytes(0);
28852885 CheckForNonNull = true;
28862886 }
2887 } else if (const LoadInst *LI = dyn_cast(BV)) {
2888 if (MDNode *MD = LI->getMetadata(LLVMContext::MD_dereferenceable)) {
2889 ConstantInt *CI = mdconst::extract(MD->getOperand(0));
2890 DerefBytes = CI->getLimitedValue();
2891 }
2892 if (!DerefBytes.getBoolValue()) {
2893 if (MDNode *MD =
2894 LI->getMetadata(LLVMContext::MD_dereferenceable_or_null)) {
2895 ConstantInt *CI = mdconst::extract(MD->getOperand(0));
2896 DerefBytes = CI->getLimitedValue();
2897 }
2898 CheckForNonNull = true;
2899 }
28872900 }
28882901
28892902 if (DerefBytes.getBoolValue())
8787 "mem_parallel_loop_access kind id drifted");
8888 (void)MemParallelLoopAccessID;
8989
90
9190 // Create the 'nonnull' metadata kind.
9291 unsigned NonNullID = getMDKindID("nonnull");
9392 assert(NonNullID == MD_nonnull && "nonnull kind id drifted");
9493 (void)NonNullID;
94
95 // Create the 'dereferenceable' metadata kind.
96 unsigned DereferenceableID = getMDKindID("dereferenceable");
97 assert(DereferenceableID == MD_dereferenceable &&
98 "dereferenceable kind id drifted");
99 (void)DereferenceableID;
100
101 // Create the 'dereferenceable_or_null' metadata kind.
102 unsigned DereferenceableOrNullID = getMDKindID("dereferenceable_or_null");
103 assert(DereferenceableOrNullID == MD_dereferenceable_or_null &&
104 "dereferenceable_or_null kind id drifted");
105 (void)DereferenceableOrNullID;
95106 }
96107 LLVMContext::~LLVMContext() { delete pImpl; }
97108
77 declare zeroext i1 @return_i1()
88
99 @globalstr = global [6 x i8] c"hello\00"
10 @globali32ptr = external global i32*
1011
1112 define void @test(i32 addrspace(1)* dereferenceable(8) %dparam) gc "statepoint-example" {
1213 ; CHECK: The following are dereferenceable:
1415 ; CHECK: %alloca
1516 ; CHECK: %dparam
1617 ; CHECK: %relocate
18 ; CHECK: %d4_load
19 ; CHECK: %d_or_null_non_null_load
1720 ; CHECK-NOT: %nparam
21 ; CHECK-NOT: %nd_load
22 ; CHECK-NOT: %d2_load
23 ; CHECK-NOT: %d_or_null_load
1824 entry:
1925 %globalptr = getelementptr inbounds [6 x i8], [6 x i8]* @globalstr, i32 0, i32 0
2026 %load1 = load i8, i8* %globalptr
2632 %load4 = load i32, i32 addrspace(1)* %relocate
2733 %nparam = getelementptr i32, i32 addrspace(1)* %dparam, i32 5
2834 %load5 = load i32, i32 addrspace(1)* %nparam
35
36 ; Load from a non-dereferenceable load
37 %nd_load = load i32*, i32** @globali32ptr, !dereferenceable !0
38 %load6 = load i32, i32* %nd_load
39
40 ; Load from a dereferenceable load
41 %d4_load = load i32*, i32** @globali32ptr, !dereferenceable !0
42 %load7 = load i32, i32* %d4_load
43
44 ; Load from an offset not covered by the dereferenceable portion
45 %d2_load = load i32*, i32** @globali32ptr, !dereferenceable !1
46 %load8 = load i32, i32* %d2_load
47
48 ; Load from a potentially null pointer with dereferenceable_or_null
49 %d_or_null_load = load i32*, i32** @globali32ptr, !dereferenceable_or_null !0
50 %load9 = load i32, i32* %d_or_null_load
51
52 ; Load from a non-null pointer with dereferenceable_or_null
53 %d_or_null_non_null_load = load i32*, i32** @globali32ptr, !nonnull !2, !dereferenceable_or_null !0
54 %load10 = load i32, i32* %d_or_null_non_null_load
55
2956 ret void
3057 }
3158
3259 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
33 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
60 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)
61
62 !0 = !{i64 4}
63 !1 = !{i64 2}
64 !2 = !{}
253253 ret i1 %not_null
254254 }
255255
256 ; This test represents the following function:
257 ; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
258 ; c = *cptr;
259 ; for (int i = 0; i < n; ++i)
260 ; if (a[i] > 0)
261 ; a[i] = (*c)*b[i];
262 ; }
263 ; and we want to hoist the load of %c out of the loop. This can be done only
264 ; because the dereferenceable meatdata on the c = *cptr load.
265
266 ; CHECK-LABEL: @test7
267 ; CHECK: load i32, i32* %c, align 4
268 ; CHECK: for.body:
269
270 define void @test7(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
271 entry:
272 %c = load i32*, i32** %cptr, !dereferenceable !0
273 %cmp11 = icmp sgt i32 %n, 0
274 br i1 %cmp11, label %for.body, label %for.end
275
276 for.body: ; preds = %entry, %for.inc
277 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
278 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
279 %0 = load i32, i32* %arrayidx, align 4
280 %cmp1 = icmp sgt i32 %0, 0
281 br i1 %cmp1, label %if.then, label %for.inc
282
283 if.then: ; preds = %for.body
284 %1 = load i32, i32* %c, align 4
285 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
286 %2 = load i32, i32* %arrayidx3, align 4
287 %mul = mul nsw i32 %2, %1
288 store i32 %mul, i32* %arrayidx, align 4
289 br label %for.inc
290
291 for.inc: ; preds = %for.body, %if.then
292 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
293 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
294 %exitcond = icmp eq i32 %lftr.wideiv, %n
295 br i1 %exitcond, label %for.end, label %for.body
296
297 for.end: ; preds = %for.inc, %entry
298 ret void
299 }
300
301 ; This test represents the following function:
302 ; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
303 ; c = *cptr;
304 ; if (c != null)
305 ; for (int i = 0; i < n; ++i)
306 ; if (a[i] > 0)
307 ; a[i] = (*c)*b[i];
308 ; }
309 ; and we want to hoist the load of %c out of the loop. This can be done only
310 ; because the dereferenceable_or_null meatdata on the c = *cptr load and there
311 ; is a null check on %c.
312
313 ; CHECK-LABEL: @test8
314 ; CHECK: load i32, i32* %c, align 4
315 ; CHECK: for.body:
316
317 define void @test8(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
318 entry:
319 %c = load i32*, i32** %cptr, !dereferenceable_or_null !0
320 %not_null = icmp ne i32* %c, null
321 br i1 %not_null, label %not.null, label %for.end
322
323 not.null:
324 %cmp11 = icmp sgt i32 %n, 0
325 br i1 %cmp11, label %for.body, label %for.end
326
327 for.body: ; preds = %not.null, %for.inc
328 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]
329 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
330 %0 = load i32, i32* %arrayidx, align 4
331 %cmp1 = icmp sgt i32 %0, 0
332 br i1 %cmp1, label %if.then, label %for.inc
333
334 if.then: ; preds = %for.body
335 %1 = load i32, i32* %c, align 4
336 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
337 %2 = load i32, i32* %arrayidx3, align 4
338 %mul = mul nsw i32 %2, %1
339 store i32 %mul, i32* %arrayidx, align 4
340 br label %for.inc
341
342 for.inc: ; preds = %for.body, %if.then
343 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
344 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
345 %exitcond = icmp eq i32 %lftr.wideiv, %n
346 br i1 %exitcond, label %for.end, label %for.body
347
348 for.end: ; preds = %for.inc, %entry, %not.null
349 ret void
350 }
351
352 ; This is the same as @test8, but without the null check on %c.
353 ; Without this check, we should not hoist the load of %c.
354
355 ; CHECK-LABEL: @test9
356 ; CHECK: if.then:
357 ; CHECK: load i32, i32* %c, align 4
358
359 define void @test9(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
360 entry:
361 %c = load i32*, i32** %cptr, !dereferenceable_or_null !0
362 %cmp11 = icmp sgt i32 %n, 0
363 br i1 %cmp11, label %for.body, label %for.end
364
365 for.body: ; preds = %entry, %for.inc
366 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
367 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
368 %0 = load i32, i32* %arrayidx, align 4
369 %cmp1 = icmp sgt i32 %0, 0
370 br i1 %cmp1, label %if.then, label %for.inc
371
372 if.then: ; preds = %for.body
373 %1 = load i32, i32* %c, align 4
374 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
375 %2 = load i32, i32* %arrayidx3, align 4
376 %mul = mul nsw i32 %2, %1
377 store i32 %mul, i32* %arrayidx, align 4
378 br label %for.inc
379
380 for.inc: ; preds = %for.body, %if.then
381 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
382 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
383 %exitcond = icmp eq i32 %lftr.wideiv, %n
384 br i1 %exitcond, label %for.end, label %for.body
385
386 for.end: ; preds = %for.inc, %entry
387 ret void
388 }
389
256390 attributes #0 = { nounwind uwtable }
257
391 !0 = !{i64 4}