1 ; RUN: opt -inline -S < %s | FileCheck %s 2 3 ; The callee guarantees that the pointer argument is nonnull and dereferenceable. 4 ; That information should transfer to the caller. 5 6 define i32 @callee(i32* dereferenceable(32) %t1) { 7 ; CHECK-LABEL: @callee(i32* dereferenceable(32) %t1) 8 ; CHECK-NEXT: [[T2:%.*]] = load i32, i32* %t1 9 ; CHECK-NEXT: ret i32 [[T2]] 10 ; 11 %t2 = load i32, i32* %t1 12 ret i32 %t2 13 } 14 15 ; FIXME: All dereferenceability information is lost. 16 ; The caller argument could be known nonnull and dereferenceable(32). 17 18 define i32 @caller1(i32* %t1) { 19 ; CHECK-LABEL: @caller1(i32* %t1) 20 ; CHECK-NEXT: [[T2_I:%.*]] = load i32, i32* %t1 21 ; CHECK-NEXT: ret i32 [[T2_I]] 22 ; 23 %t2 = tail call i32 @callee(i32* dereferenceable(32) %t1) 24 ret i32 %t2 25 } 26 27 ; The caller argument is nonnull, but that can be explicit. 28 ; The dereferenceable amount could be increased. 29 30 define i32 @caller2(i32* dereferenceable(31) %t1) { 31 ; CHECK-LABEL: @caller2(i32* dereferenceable(31) %t1) 32 ; CHECK-NEXT: [[T2_I:%.*]] = load i32, i32* %t1 33 ; CHECK-NEXT: ret i32 [[T2_I]] 34 ; 35 %t2 = tail call i32 @callee(i32* dereferenceable(32) %t1) 36 ret i32 %t2 37 } 38 39 ; The caller argument is nonnull, but that can be explicit. 40 ; Make sure that we don't propagate a smaller dereferenceable amount. 41 42 define i32 @caller3(i32* dereferenceable(33) %t1) { 43 ; CHECK-LABEL: @caller3(i32* dereferenceable(33) %t1) 44 ; CHECK-NEXT: [[T2_I:%.*]] = load i32, i32* %t1 45 ; CHECK-NEXT: ret i32 [[T2_I]] 46 ; 47 %t2 = tail call i32 @callee(i32* dereferenceable(32) %t1) 48 ret i32 %t2 49 } 50 51