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: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0)) 16; CHECK-NEXT: ret i32 [[CMP]] 17; 18 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 19 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0 20 21 %cmp = call i32 @strcmp(i8* %p, i8* %q) 22 ret i32 %cmp 23} 24 25 26; Do not fold strcmp(a5[0], a5[I]) where the index I is not constant. 27 28define i32 @call_strcmp_a5i0_a5iI(i64 %I) { 29; CHECK-LABEL: @call_strcmp_a5i0_a5iI( 30; CHECK-NEXT: [[Q:%.*]] = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 [[I:%.*]], i64 0 31; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) 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]]) 32; CHECK-NEXT: ret i32 [[CMP]] 33; 34 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 35 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 %I, i64 0 36 37 %cmp = call i32 @strcmp(i8* %p, i8* %q) 38 ret i32 %cmp 39} 40 41 42; Same as above but for strcmp(a5[I], a5[0]). 43 44define i32 @call_strcmp_a5iI_a5i0(i64 %I) { 45; CHECK-LABEL: @call_strcmp_a5iI_a5i0( 46; CHECK-NEXT: [[P:%.*]] = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 [[I:%.*]], i64 0 47; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) [[P]], i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0)) 48; CHECK-NEXT: ret i32 [[CMP]] 49; 50 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 %I, i64 0 51 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 52 53 %cmp = call i32 @strcmp(i8* %p, i8* %q) 54 ret i32 %cmp 55} 56 57 58; Fold strcmp(a5[0], &a5[1][1]) to '1' - '2'. 59 60define i32 @fold_strcmp_a5i0_a5i1_p1_to_0() { 61; CHECK-LABEL: @fold_strcmp_a5i0_a5i1_p1_to_0( 62; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 1)) 63; CHECK-NEXT: ret i32 [[CMP]] 64; 65 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 66 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 1 67 68 %cmp = call i32 @strcmp(i8* %p, i8* %q) 69 ret i32 %cmp 70} 71 72 73; Do not fold strcmp(a5[0], &a5[1][I]) when the index I is not constant. 74 75define i32 @call_strcmp_a5i0_a5i1_pI(i64 %I) { 76; CHECK-LABEL: @call_strcmp_a5i0_a5i1_pI( 77; CHECK-NEXT: [[Q:%.*]] = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 [[I:%.*]] 78; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) 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]]) 79; CHECK-NEXT: ret i32 [[CMP]] 80; 81 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 82 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 %I 83 84 %cmp = call i32 @strcmp(i8* %p, i8* %q) 85 ret i32 %cmp 86} 87 88 89; Fold strcmp(&a5[0][1], a5[1]) to '2' - '1'. 90 91define i32 @fold_strcmp_a5i0_p1_a5i1_to_0() { 92; CHECK-LABEL: @fold_strcmp_a5i0_p1_a5i1_to_0( 93; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 1), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0)) 94; CHECK-NEXT: ret i32 [[CMP]] 95; 96 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 1 97 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0 98 99 %cmp = call i32 @strcmp(i8* %p, i8* %q) 100 ret i32 %cmp 101} 102 103 104; Fold strcmp(a5[0], a5[2]) to a5[0][2] - a5[2][2] or 1. 105 106define i32 @fold_strcmp_a5i0_a5i2_to_0() { 107; CHECK-LABEL: @fold_strcmp_a5i0_a5i2_to_0( 108; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0)) 109; CHECK-NEXT: ret i32 [[CMP]] 110; 111 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 112 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0 113 114 %cmp = call i32 @strcmp(i8* %p, i8* %q) 115 ret i32 %cmp 116} 117 118 119; Fold strcmp(a5[2], a5[0]) to a5[0][2] - a5[2][2] or 1. 120 121define i32 @fold_strcmp_a5i2_a5i0_to_m1() { 122; CHECK-LABEL: @fold_strcmp_a5i2_a5i0_to_m1( 123; CHECK-NEXT: [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0)) 124; CHECK-NEXT: ret i32 [[CMP]] 125; 126 %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0 127 %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0 128 129 %cmp = call i32 @strcmp(i8* %q, i8* %p) 130 ret i32 %cmp 131} 132