1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; Verify that strnlen calls that aren't folded into constants are annotated 3; with noundef, nonnull, and dereferenceable only when maxlen is known to 4; to be nonzero. 5; 6; RUN: opt < %s -passes=instcombine -S | FileCheck %s 7 8declare i64 @strnlen(ptr, i64) 9 10@ecp = external global ptr, align 8 11 12 13; Annotate strnlen(ecp, 3) call with noundef, nonnull, and dereferenceable 14; based on the access to *ecp. 15 16define i64 @deref_strnlen_ecp_3() { 17; CHECK-LABEL: @deref_strnlen_ecp_3( 18; CHECK-NEXT: [[PTR:%.*]] = load ptr, ptr @ecp, align 8 19; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) [[PTR]], i64 3) 20; CHECK-NEXT: ret i64 [[LEN]] 21; 22 %ptr = load ptr, ptr @ecp 23 %len = call i64 @strnlen(ptr %ptr, i64 3) 24 ret i64 %len 25} 26 27 28; Annotate strnlen(ecp, %n) call with nonzero %n with noundef, nonnull, and 29; dereferenceable based on the access to *ecp. 30 31define i64 @deref_strnlen_ecp_nz(i64 %n) { 32; CHECK-LABEL: @deref_strnlen_ecp_nz( 33; CHECK-NEXT: [[NONZERO:%.*]] = or i64 [[N:%.*]], 1 34; CHECK-NEXT: [[PTR:%.*]] = load ptr, ptr @ecp, align 8 35; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) [[PTR]], i64 [[NONZERO]]) 36; CHECK-NEXT: ret i64 [[LEN]] 37; 38 %nonzero = or i64 %n, 1 39 %ptr = load ptr, ptr @ecp 40 %len = call i64 @strnlen(ptr %ptr, i64 %nonzero) 41 ret i64 %len 42} 43 44 45 46; Do not annotate strnlen(ecp, %n) call with nonnull etc. because it need 47; not access *ecp. (Strictly, every pointer function argument must be 48; noundef, so this is overly conservative.) 49 50 51define i64 @noderef_strnlen_ecp_n(i64 %n) { 52; CHECK-LABEL: @noderef_strnlen_ecp_n( 53; CHECK-NEXT: [[PTR:%.*]] = load ptr, ptr @ecp, align 8 54; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr [[PTR]], i64 [[N:%.*]]) 55; CHECK-NEXT: ret i64 [[LEN]] 56; 57 %ptr = load ptr, ptr @ecp 58 %len = call i64 @strnlen(ptr %ptr, i64 %n) 59 ret i64 %len 60} 61