1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3; 4; Exercise folding of strncmp calls with constant arrays including both 5; negative and positive characters and both constant and nonconstant sizes. 6 7declare i32 @strncmp(ptr, ptr, i64) 8 9@a = constant [7 x i8] c"abcdef\7f" 10@b = constant [7 x i8] c"abcdef\80" 11 12 13; Exercise strncmp(A + C, B + C, 2) folding of small arrays that differ in 14; a character with the opposite sign and a constant size. 15 16define void @fold_strncmp_cst_cst(ptr %pcmp) { 17; CHECK-LABEL: @fold_strncmp_cst_cst( 18; CHECK-NEXT: store i32 -1, ptr [[PCMP:%.*]], align 4 19; CHECK-NEXT: [[SB5_A5:%.*]] = getelementptr i8, ptr [[PCMP]], i64 4 20; CHECK-NEXT: store i32 1, ptr [[SB5_A5]], align 4 21; CHECK-NEXT: [[SA6_B6:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8 22; CHECK-NEXT: store i32 -1, ptr [[SA6_B6]], align 4 23; CHECK-NEXT: [[SB6_A6:%.*]] = getelementptr i8, ptr [[PCMP]], i64 12 24; CHECK-NEXT: store i32 1, ptr [[SB6_A6]], align 4 25; CHECK-NEXT: ret void 26; 27 %p5 = getelementptr [7 x i8], ptr @a, i64 0, i64 5 28 %p6 = getelementptr [7 x i8], ptr @a, i64 0, i64 6 29 30 %q5 = getelementptr [7 x i8], ptr @b, i64 0, i64 5 31 %q6 = getelementptr [7 x i8], ptr @b, i64 0, i64 6 32 33 ; Fold strncmp(a + 5, b + 5, 2) to -1. 34 %ca5_b5 = call i32 @strncmp(ptr %p5, ptr %q5, i64 2) 35 store i32 %ca5_b5, ptr %pcmp 36 37 ; Fold strncmp(b + 5, a + 5, 2) to +1. 38 %cb5_a5 = call i32 @strncmp(ptr %q5, ptr %p5, i64 2) 39 %sb5_a5 = getelementptr i32, ptr %pcmp, i64 1 40 store i32 %cb5_a5, ptr %sb5_a5 41 42 ; Fold strncmp(a + 6, b + 6, 1) to -1. 43 %ca6_b6 = call i32 @strncmp(ptr %p6, ptr %q6, i64 1) 44 %sa6_b6 = getelementptr i32, ptr %pcmp, i64 2 45 store i32 %ca6_b6, ptr %sa6_b6 46 47 ; Fold strncmp(b + 6, a + 6, 1) to +1. 48 %cb6_a6 = call i32 @strncmp(ptr %q6, ptr %p6, i64 1) 49 %sb6_a6 = getelementptr i32, ptr %pcmp, i64 3 50 store i32 %cb6_a6, ptr %sb6_a6 51 52 ret void 53} 54 55 56; Exercise strncmp(A, B, N) folding of arrays that differ in a character 57; with the opposite sign and a variable size 58 59define void @fold_strncmp_cst_var(ptr %pcmp, i64 %n) { 60; CHECK-LABEL: @fold_strncmp_cst_var( 61; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i64 [[N:%.*]], 6 62; CHECK-NEXT: [[CA0_B0:%.*]] = sext i1 [[TMP1]] to i32 63; CHECK-NEXT: store i32 [[CA0_B0]], ptr [[PCMP:%.*]], align 4 64; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i64 [[N]], 6 65; CHECK-NEXT: [[CB0_A0:%.*]] = zext i1 [[TMP2]] to i32 66; CHECK-NEXT: [[SB0_A0:%.*]] = getelementptr i8, ptr [[PCMP]], i64 4 67; CHECK-NEXT: store i32 [[CB0_A0]], ptr [[SB0_A0]], align 4 68; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i64 [[N]], 0 69; CHECK-NEXT: [[CA6_B6:%.*]] = sext i1 [[TMP3]] to i32 70; CHECK-NEXT: [[SA6_B6:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8 71; CHECK-NEXT: store i32 [[CA6_B6]], ptr [[SA6_B6]], align 4 72; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i64 [[N]], 0 73; CHECK-NEXT: [[CB6_A6:%.*]] = zext i1 [[TMP4]] to i32 74; CHECK-NEXT: [[SB6_A6:%.*]] = getelementptr i8, ptr [[PCMP]], i64 12 75; CHECK-NEXT: store i32 [[CB6_A6]], ptr [[SB6_A6]], align 4 76; CHECK-NEXT: ret void 77; 78 %p6 = getelementptr [7 x i8], ptr @a, i64 0, i64 6 79 80 %q6 = getelementptr [7 x i8], ptr @b, i64 0, i64 6 81 82 ; Fold strncmp(a, b, n) to -1. 83 %ca0_b0 = call i32 @strncmp(ptr @a, ptr @b, i64 %n) 84 store i32 %ca0_b0, ptr %pcmp 85 86 ; Fold strncmp(b, a, n) to +1. 87 %cb0_a0 = call i32 @strncmp(ptr @b, ptr @a, i64 %n) 88 %sb0_a0 = getelementptr i32, ptr %pcmp, i64 1 89 store i32 %cb0_a0, ptr %sb0_a0 90 91 ; Fold strncmp(a + 6, b + 6, n) to -1. 92 %ca6_b6 = call i32 @strncmp(ptr %p6, ptr %q6, i64 %n) 93 %sa6_b6 = getelementptr i32, ptr %pcmp, i64 2 94 store i32 %ca6_b6, ptr %sa6_b6 95 96 ; Fold strncmp(b + 6, a + 6, n) to +1. 97 %cb6_a6 = call i32 @strncmp(ptr %q6, ptr %p6, i64 %n) 98 %sb6_a6 = getelementptr i32, ptr %pcmp, i64 3 99 store i32 %cb6_a6, ptr %sb6_a6 100 101 ret void 102} 103