1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; Verify that strlen calls with variable offsets into elements of constant 3; arrays are folded. 4; 5; TODO: None of these cases is folded at the moment due to a limitation 6; in LibCallSimplifier::optimizeStringLength. 7; 8; RUN: opt < %s -passes=instcombine -S | FileCheck %s 9 10declare i64 @strlen(ptr) 11 12@a5_4 = constant [5 x [4 x i8]] [[4 x i8] c"123\00", [4 x i8] c"12\00\00", [4 x i8] c"1\00\00\00", [4 x i8] zeroinitializer, [4 x i8] zeroinitializer] 13 14 15; Fold strlen(&a5_4[0][I]) to I <= 3 ? 3 - I : 0. 16 17define i64 @fold_a5_4_i0_pI(i64 %I) { 18; CHECK-LABEL: @fold_a5_4_i0_pI( 19; CHECK-NEXT: [[PTR:%.*]] = getelementptr [5 x [4 x i8]], ptr @a5_4, i64 0, i64 0, i64 [[I:%.*]] 20; CHECK-NEXT: [[LEN:%.*]] = call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[PTR]]) 21; CHECK-NEXT: ret i64 [[LEN]] 22; 23 %ptr = getelementptr [5 x [4 x i8]], ptr @a5_4, i64 0, i64 0, i64 %I 24 %len = call i64 @strlen(ptr %ptr) 25 ret i64 %len 26} 27 28 29; Fold strlen(&a5_4[1][I]) to I <= 2 ? 2 - I : 0. 30 31define i64 @fold_a5_4_i1_pI(i64 %I) { 32; CHECK-LABEL: @fold_a5_4_i1_pI( 33; CHECK-NEXT: [[PTR:%.*]] = getelementptr [5 x [4 x i8]], ptr @a5_4, i64 0, i64 1, i64 [[I:%.*]] 34; CHECK-NEXT: [[LEN:%.*]] = call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[PTR]]) 35; CHECK-NEXT: ret i64 [[LEN]] 36; 37 %ptr = getelementptr [5 x [4 x i8]], ptr @a5_4, i64 0, i64 1, i64 %I 38 %len = call i64 @strlen(ptr %ptr) 39 ret i64 %len 40} 41 42 43; Fold strlen(&a5_4[2][I]) to i <= 1 ? 1 - I : 0. 44 45define i64 @fold_a5_4_i2_pI(i64 %I) { 46; CHECK-LABEL: @fold_a5_4_i2_pI( 47; CHECK-NEXT: [[PTR:%.*]] = getelementptr [5 x [4 x i8]], ptr @a5_4, i64 0, i64 2, i64 [[I:%.*]] 48; CHECK-NEXT: [[LEN:%.*]] = call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[PTR]]) 49; CHECK-NEXT: ret i64 [[LEN]] 50; 51 %ptr = getelementptr [5 x [4 x i8]], ptr @a5_4, i64 0, i64 2, i64 %I 52 %len = call i64 @strlen(ptr %ptr) 53 ret i64 %len 54} 55 56 57; Fold strlen(&a5_4[3][I]) to 0. 58 59define i64 @fold_a5_4_i3_pI_to_0(i64 %I) { 60; CHECK-LABEL: @fold_a5_4_i3_pI_to_0( 61; CHECK-NEXT: [[PTR:%.*]] = getelementptr [5 x [4 x i8]], ptr @a5_4, i64 0, i64 3, i64 [[I:%.*]] 62; CHECK-NEXT: [[LEN:%.*]] = call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[PTR]]) 63; CHECK-NEXT: ret i64 [[LEN]] 64; 65 %ptr = getelementptr [5 x [4 x i8]], ptr @a5_4, i64 0, i64 3, i64 %I 66 %len = call i64 @strlen(ptr %ptr) 67 ret i64 %len 68} 69 70 71; Fold strlen(&a5_4[4][I]) to 0. 72 73define i64 @fold_a5_4_i4_pI_to_0(i64 %I) { 74; CHECK-LABEL: @fold_a5_4_i4_pI_to_0( 75; CHECK-NEXT: [[PTR:%.*]] = getelementptr [5 x [4 x i8]], ptr @a5_4, i64 0, i64 4, i64 [[I:%.*]] 76; CHECK-NEXT: [[LEN:%.*]] = call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[PTR]]) 77; CHECK-NEXT: ret i64 [[LEN]] 78; 79 %ptr = getelementptr [5 x [4 x i8]], ptr @a5_4, i64 0, i64 4, i64 %I 80 %len = call i64 @strlen(ptr %ptr) 81 ret i64 %len 82} 83