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 6define 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 18define 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 30define 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 42define 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