214 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; Verify that equality tests of strnlen calls against zero are folded3; correctly.4;5; RUN: opt < %s -passes=instcombine -S | FileCheck %s6 7declare i64 @strnlen(ptr, i64)8 9@ax = external global [0 x i8]10@a5 = external global [5 x i8]11@s5 = constant [6 x i8] c"12345\00"12 13 14; Fold strnlen(ax, 0) == 0 to true.15 16define i1 @fold_strnlen_ax_0_eqz() {17; CHECK-LABEL: @fold_strnlen_ax_0_eqz(18; CHECK-NEXT: ret i1 true19;20 21 %len = tail call i64 @strnlen(ptr @ax, i64 0)22 %eqz = icmp eq i64 %len, 023 ret i1 %eqz24}25 26 27; Fold strnlen(ax, 0) > 0 to false.28 29define i1 @fold_strnlen_ax_0_gtz() {30; CHECK-LABEL: @fold_strnlen_ax_0_gtz(31; CHECK-NEXT: ret i1 false32;33 34 %len = tail call i64 @strnlen(ptr @ax, i64 0)35 %gtz = icmp ugt i64 %len, 036 ret i1 %gtz37}38 39 40; Fold strnlen(ax, 1) == 0 to *ax == 0.41 42define i1 @fold_strnlen_ax_1_eqz() {43; CHECK-LABEL: @fold_strnlen_ax_1_eqz(44; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 145; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 046; CHECK-NEXT: ret i1 [[EQZ]]47;48 49 %len = tail call i64 @strnlen(ptr @ax, i64 1)50 %eqz = icmp eq i64 %len, 051 ret i1 %eqz52}53 54 55; Likewise, fold strnlen(ax, 1) < 1 to *ax == 0.56 57define i1 @fold_strnlen_ax_1_lt1() {58; CHECK-LABEL: @fold_strnlen_ax_1_lt1(59; CHECK-NEXT: [[STRNLEN_CHAR0:%.*]] = load i8, ptr @ax, align 160; CHECK-NEXT: [[STRNLEN_CHAR0CMP_NOT:%.*]] = icmp eq i8 [[STRNLEN_CHAR0]], 061; CHECK-NEXT: ret i1 [[STRNLEN_CHAR0CMP_NOT]]62;63 64 %len = tail call i64 @strnlen(ptr @ax, i64 1)65 %nez = icmp ult i64 %len, 166 ret i1 %nez67}68 69 70; Fold strnlen(ax, 1) != 0 to *ax != 0.71 72define i1 @fold_strnlen_ax_1_neqz() {73; CHECK-LABEL: @fold_strnlen_ax_1_neqz(74; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 175; CHECK-NEXT: [[NEZ:%.*]] = icmp ne i8 [[CHAR0]], 076; CHECK-NEXT: ret i1 [[NEZ]]77;78 79 %len = tail call i64 @strnlen(ptr @ax, i64 1)80 %nez = icmp ne i64 %len, 081 ret i1 %nez82}83 84 85; Likewise, fold strnlen(ax, 1) > 0 to *ax != 0.86 87define i1 @fold_strnlen_ax_1_gtz() {88; CHECK-LABEL: @fold_strnlen_ax_1_gtz(89; CHECK-NEXT: [[STRNLEN_CHAR0:%.*]] = load i8, ptr @ax, align 190; CHECK-NEXT: [[STRNLEN_CHAR0CMP:%.*]] = icmp ne i8 [[STRNLEN_CHAR0]], 091; CHECK-NEXT: ret i1 [[STRNLEN_CHAR0CMP]]92;93 94 %len = tail call i64 @strnlen(ptr @ax, i64 1)95 %nez = icmp ugt i64 %len, 096 ret i1 %nez97}98 99 100; Fold strnlen(ax, 9) == 0 to *ax == 0.101 102define i1 @fold_strnlen_ax_9_eqz() {103; CHECK-LABEL: @fold_strnlen_ax_9_eqz(104; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 1105; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0106; CHECK-NEXT: ret i1 [[EQZ]]107;108 109 %len = tail call i64 @strnlen(ptr @ax, i64 9)110 %eqz = icmp eq i64 %len, 0111 ret i1 %eqz112}113 114 115; Do not fold strnlen(ax, n) == 0 for n that might be zero.116 117define i1 @call_strnlen_ax_n_eqz(i64 %n) {118; CHECK-LABEL: @call_strnlen_ax_n_eqz(119; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(ptr nonnull @ax, i64 [[N:%.*]])120; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0121; CHECK-NEXT: ret i1 [[EQZ]]122;123 124 %len = tail call i64 @strnlen(ptr @ax, i64 %n)125 %eqz = icmp eq i64 %len, 0126 ret i1 %eqz127}128 129 130; Fold strnlen(ax, n) == 0 to *ax == 0 for %0 that's not zero.131 132define i1 @fold_strnlen_ax_nz_eqz(i64 %n) {133; CHECK-LABEL: @fold_strnlen_ax_nz_eqz(134; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 1135; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0136; CHECK-NEXT: ret i1 [[EQZ]]137;138 139 %max = or i64 %n, 1140 %len = tail call i64 @strnlen(ptr @ax, i64 %max)141 %eqz = icmp eq i64 %len, 0142 ret i1 %eqz143}144 145 146; Fold strnlen(ax, n) > 0 to *ax != 0 for n that's not zero.147 148define i1 @fold_strnlen_ax_nz_gtz(i64 %n) {149; CHECK-LABEL: @fold_strnlen_ax_nz_gtz(150; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 1151; CHECK-NEXT: [[GTZ:%.*]] = icmp ne i8 [[CHAR0]], 0152; CHECK-NEXT: ret i1 [[GTZ]]153;154 155 %max = or i64 %n, 1156 %len = tail call i64 @strnlen(ptr @ax, i64 %max)157 %gtz = icmp ugt i64 %len, 0158 ret i1 %gtz159}160 161 162; Fold strnlen(a5 + i, n) == 0 to a5[i] == 0 for a nonconstant a5163; and a nonzero n.164 165define i1 @fold_strnlen_a5_pi_nz_eqz(i64 %i, i64 %n) {166; CHECK-LABEL: @fold_strnlen_a5_pi_nz_eqz(167; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds i8, ptr @a5, i64 [[I:%.*]]168; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr [[PTR]], align 1169; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0170; CHECK-NEXT: ret i1 [[EQZ]]171;172 173 %nz = or i64 %n, 1174 %ptr = getelementptr inbounds [5 x i8], ptr @a5, i64 0, i64 %i175 %len = call i64 @strnlen(ptr %ptr, i64 %nz)176 %eqz = icmp eq i64 %len, 0177 ret i1 %eqz178}179 180 181; Fold strnlen(s5 + i, n) == 0 for a constant s5 and nonzero n.182; This is first folded to s5[i] == 0 like the above and then finally183; to %0 == 5.184 185define i1 @fold_strnlen_s5_pi_nz_eqz(i64 %i, i64 %n) {186; CHECK-LABEL: @fold_strnlen_s5_pi_nz_eqz(187; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[I:%.*]], 5188; CHECK-NEXT: ret i1 [[EQZ]]189;190 191 %nz = or i64 %n, 1192 %ptr = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 %i193 %len = call i64 @strnlen(ptr %ptr, i64 %nz)194 %eqz = icmp eq i64 %len, 0195 ret i1 %eqz196}197 198 199; Do not fold strnlen(s5 + i, n) for a constant s5 when n might be zero.200 201define i1 @call_strnlen_s5_pi_n_eqz(i64 %i, i64 %n) {202; CHECK-LABEL: @call_strnlen_s5_pi_n_eqz(203; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds i8, ptr @s5, i64 [[I:%.*]]204; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr nonnull [[PTR]], i64 [[N:%.*]])205; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0206; CHECK-NEXT: ret i1 [[EQZ]]207;208 209 %ptr = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 %i210 %len = call i64 @strnlen(ptr %ptr, i64 %n)211 %eqz = icmp eq i64 %len, 0212 ret i1 %eqz213}214