1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; Verify that strlen calls with elements of constant arrays are folded. 3; 4; RUN: opt < %s -passes=instcombine -S | FileCheck %s 5 6declare i32 @strcmp(i8*, i8*) 7 8@a5 = constant [5 x [4 x i8]] [[4 x i8] c"123\00", [4 x i8] c"123\00", [4 x i8] c"12\00\00", [4 x i8] zeroinitializer, [4 x i8] zeroinitializer] 9 10 11; Fold strcmp(a5[0], a5[1]) to '1' - '1'. 12 13define i32 @fold_strcmp_a5i0_a5i1_to_0() { 14; CHECK-LABEL: @fold_strcmp_a5i0_a5i1_to_0( 15; CHECK-NEXT: ret i32 0 16; 17 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 18 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0 19 20 %cmp = call i32 @strcmp(i8* %p, i8* %q) 21 ret i32 %cmp 22} 23 24 25; Do not fold strcmp(a5[0], a5[I]) where the index I is not constant. 26 27define i32 @call_strcmp_a5i0_a5iI(i64 %I) { 28; CHECK-LABEL: @call_strcmp_a5i0_a5iI( 29; CHECK-NEXT: [[Q:%.*]] = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 [[I:%.*]], i64 0 30; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) [[Q]]) 31; CHECK-NEXT: ret i32 [[CMP]] 32; 33 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 34 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 %I, i64 0 35 36 %cmp = call i32 @strcmp(i8* %p, i8* %q) 37 ret i32 %cmp 38} 39 40 41; Same as above but for strcmp(a5[I], a5[0]). 42 43define i32 @call_strcmp_a5iI_a5i0(i64 %I) { 44; CHECK-LABEL: @call_strcmp_a5iI_a5i0( 45; CHECK-NEXT: [[P:%.*]] = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 [[I:%.*]], i64 0 46; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) [[P]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0)) 47; CHECK-NEXT: ret i32 [[CMP]] 48; 49 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 %I, i64 0 50 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 51 52 %cmp = call i32 @strcmp(i8* %p, i8* %q) 53 ret i32 %cmp 54} 55 56 57; Fold strcmp(a5[0], &a5[1][1]) to '1' - '2'. 58 59define i32 @fold_strcmp_a5i0_a5i1_p1_to_0() { 60; CHECK-LABEL: @fold_strcmp_a5i0_a5i1_p1_to_0( 61; CHECK-NEXT: ret i32 -1 62; 63 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 64 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 1 65 66 %cmp = call i32 @strcmp(i8* %p, i8* %q) 67 ret i32 %cmp 68} 69 70 71; Do not fold strcmp(a5[0], &a5[1][I]) when the index I is not constant. 72 73define i32 @call_strcmp_a5i0_a5i1_pI(i64 %I) { 74; CHECK-LABEL: @call_strcmp_a5i0_a5i1_pI( 75; CHECK-NEXT: [[Q:%.*]] = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 [[I:%.*]] 76; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) [[Q]]) 77; CHECK-NEXT: ret i32 [[CMP]] 78; 79 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 80 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 %I 81 82 %cmp = call i32 @strcmp(i8* %p, i8* %q) 83 ret i32 %cmp 84} 85 86 87; Fold strcmp(&a5[0][1], a5[1]) to '2' - '1'. 88 89define i32 @fold_strcmp_a5i0_p1_a5i1_to_0() { 90; CHECK-LABEL: @fold_strcmp_a5i0_p1_a5i1_to_0( 91; CHECK-NEXT: ret i32 1 92; 93 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 1 94 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0 95 96 %cmp = call i32 @strcmp(i8* %p, i8* %q) 97 ret i32 %cmp 98} 99 100 101; Fold strcmp(a5[0], a5[2]) to a5[0][2] - a5[2][2] or 1. 102 103define i32 @fold_strcmp_a5i0_a5i2_to_0() { 104; CHECK-LABEL: @fold_strcmp_a5i0_a5i2_to_0( 105; CHECK-NEXT: ret i32 1 106; 107 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 108 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0 109 110 %cmp = call i32 @strcmp(i8* %p, i8* %q) 111 ret i32 %cmp 112} 113 114 115; Fold strcmp(a5[2], a5[0]) to a5[0][2] - a5[2][2] or 1. 116 117define i32 @fold_strcmp_a5i2_a5i0_to_m1() { 118; CHECK-LABEL: @fold_strcmp_a5i2_a5i0_to_m1( 119; CHECK-NEXT: ret i32 -1 120; 121 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 122 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0 123 124 %cmp = call i32 @strcmp(i8* %q, i8* %p) 125 ret i32 %cmp 126} 127