1884d7c60SMartin Sebor; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2884d7c60SMartin Sebor; Verify that equality tests of strnlen calls against zero are folded 3884d7c60SMartin Sebor; correctly. 4884d7c60SMartin Sebor; 5884d7c60SMartin Sebor; RUN: opt < %s -passes=instcombine -S | FileCheck %s 6884d7c60SMartin Sebor 7*dc2b66b8SBjorn Petterssondeclare i64 @strnlen(ptr, i64) 8884d7c60SMartin Sebor 9884d7c60SMartin Sebor@ax = external global [0 x i8] 10884d7c60SMartin Sebor@a5 = external global [5 x i8] 11884d7c60SMartin Sebor@s5 = constant [6 x i8] c"12345\00" 12884d7c60SMartin Sebor 13884d7c60SMartin Sebor 14884d7c60SMartin Sebor; Fold strnlen(ax, 0) == 0 to true. 15884d7c60SMartin Sebor 16884d7c60SMartin Sebordefine i1 @fold_strnlen_ax_0_eqz() { 17884d7c60SMartin Sebor; CHECK-LABEL: @fold_strnlen_ax_0_eqz( 1825febbd1SMartin Sebor; CHECK-NEXT: ret i1 true 19884d7c60SMartin Sebor; 20884d7c60SMartin Sebor 21*dc2b66b8SBjorn Pettersson %len = tail call i64 @strnlen(ptr @ax, i64 0) 22884d7c60SMartin Sebor %eqz = icmp eq i64 %len, 0 23884d7c60SMartin Sebor ret i1 %eqz 24884d7c60SMartin Sebor} 25884d7c60SMartin Sebor 26884d7c60SMartin Sebor 27884d7c60SMartin Sebor; Fold strnlen(ax, 0) > 0 to false. 28884d7c60SMartin Sebor 29884d7c60SMartin Sebordefine i1 @fold_strnlen_ax_0_gtz() { 30884d7c60SMartin Sebor; CHECK-LABEL: @fold_strnlen_ax_0_gtz( 3125febbd1SMartin Sebor; CHECK-NEXT: ret i1 false 32884d7c60SMartin Sebor; 33884d7c60SMartin Sebor 34*dc2b66b8SBjorn Pettersson %len = tail call i64 @strnlen(ptr @ax, i64 0) 35884d7c60SMartin Sebor %gtz = icmp ugt i64 %len, 0 36884d7c60SMartin Sebor ret i1 %gtz 37884d7c60SMartin Sebor} 38884d7c60SMartin Sebor 39884d7c60SMartin Sebor 40884d7c60SMartin Sebor; Fold strnlen(ax, 1) == 0 to *ax == 0. 41884d7c60SMartin Sebor 42884d7c60SMartin Sebordefine i1 @fold_strnlen_ax_1_eqz() { 43884d7c60SMartin Sebor; CHECK-LABEL: @fold_strnlen_ax_1_eqz( 44*dc2b66b8SBjorn Pettersson; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 1 45efa0f12cSMartin Sebor; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0 46efa0f12cSMartin Sebor; CHECK-NEXT: ret i1 [[EQZ]] 47884d7c60SMartin Sebor; 48884d7c60SMartin Sebor 49*dc2b66b8SBjorn Pettersson %len = tail call i64 @strnlen(ptr @ax, i64 1) 50884d7c60SMartin Sebor %eqz = icmp eq i64 %len, 0 51884d7c60SMartin Sebor ret i1 %eqz 52884d7c60SMartin Sebor} 53884d7c60SMartin Sebor 54884d7c60SMartin Sebor 55efa0f12cSMartin Sebor; Likewise, fold strnlen(ax, 1) < 1 to *ax == 0. 56efa0f12cSMartin Sebor 57efa0f12cSMartin Sebordefine i1 @fold_strnlen_ax_1_lt1() { 58efa0f12cSMartin Sebor; CHECK-LABEL: @fold_strnlen_ax_1_lt1( 59*dc2b66b8SBjorn Pettersson; CHECK-NEXT: [[STRNLEN_CHAR0:%.*]] = load i8, ptr @ax, align 1 60efa0f12cSMartin Sebor; CHECK-NEXT: [[STRNLEN_CHAR0CMP_NOT:%.*]] = icmp eq i8 [[STRNLEN_CHAR0]], 0 61efa0f12cSMartin Sebor; CHECK-NEXT: ret i1 [[STRNLEN_CHAR0CMP_NOT]] 62efa0f12cSMartin Sebor; 63efa0f12cSMartin Sebor 64*dc2b66b8SBjorn Pettersson %len = tail call i64 @strnlen(ptr @ax, i64 1) 65efa0f12cSMartin Sebor %nez = icmp ult i64 %len, 1 66efa0f12cSMartin Sebor ret i1 %nez 67efa0f12cSMartin Sebor} 68efa0f12cSMartin Sebor 69efa0f12cSMartin Sebor 70884d7c60SMartin Sebor; Fold strnlen(ax, 1) != 0 to *ax != 0. 71884d7c60SMartin Sebor 72884d7c60SMartin Sebordefine i1 @fold_strnlen_ax_1_neqz() { 73884d7c60SMartin Sebor; CHECK-LABEL: @fold_strnlen_ax_1_neqz( 74*dc2b66b8SBjorn Pettersson; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 1 75efa0f12cSMartin Sebor; CHECK-NEXT: [[NEZ:%.*]] = icmp ne i8 [[CHAR0]], 0 76efa0f12cSMartin Sebor; CHECK-NEXT: ret i1 [[NEZ]] 77884d7c60SMartin Sebor; 78884d7c60SMartin Sebor 79*dc2b66b8SBjorn Pettersson %len = tail call i64 @strnlen(ptr @ax, i64 1) 80884d7c60SMartin Sebor %nez = icmp ne i64 %len, 0 81884d7c60SMartin Sebor ret i1 %nez 82884d7c60SMartin Sebor} 83884d7c60SMartin Sebor 84884d7c60SMartin Sebor 85efa0f12cSMartin Sebor; Likewise, fold strnlen(ax, 1) > 0 to *ax != 0. 86efa0f12cSMartin Sebor 87efa0f12cSMartin Sebordefine i1 @fold_strnlen_ax_1_gtz() { 88efa0f12cSMartin Sebor; CHECK-LABEL: @fold_strnlen_ax_1_gtz( 89*dc2b66b8SBjorn Pettersson; CHECK-NEXT: [[STRNLEN_CHAR0:%.*]] = load i8, ptr @ax, align 1 90efa0f12cSMartin Sebor; CHECK-NEXT: [[STRNLEN_CHAR0CMP:%.*]] = icmp ne i8 [[STRNLEN_CHAR0]], 0 91efa0f12cSMartin Sebor; CHECK-NEXT: ret i1 [[STRNLEN_CHAR0CMP]] 92efa0f12cSMartin Sebor; 93efa0f12cSMartin Sebor 94*dc2b66b8SBjorn Pettersson %len = tail call i64 @strnlen(ptr @ax, i64 1) 95efa0f12cSMartin Sebor %nez = icmp ugt i64 %len, 0 96efa0f12cSMartin Sebor ret i1 %nez 97efa0f12cSMartin Sebor} 98efa0f12cSMartin Sebor 99efa0f12cSMartin Sebor 100884d7c60SMartin Sebor; Fold strnlen(ax, 9) == 0 to *ax == 0. 101884d7c60SMartin Sebor 102884d7c60SMartin Sebordefine i1 @fold_strnlen_ax_9_eqz() { 103884d7c60SMartin Sebor; CHECK-LABEL: @fold_strnlen_ax_9_eqz( 104*dc2b66b8SBjorn Pettersson; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 1 105efa0f12cSMartin Sebor; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0 106884d7c60SMartin Sebor; CHECK-NEXT: ret i1 [[EQZ]] 107884d7c60SMartin Sebor; 108884d7c60SMartin Sebor 109*dc2b66b8SBjorn Pettersson %len = tail call i64 @strnlen(ptr @ax, i64 9) 110884d7c60SMartin Sebor %eqz = icmp eq i64 %len, 0 111884d7c60SMartin Sebor ret i1 %eqz 112884d7c60SMartin Sebor} 113884d7c60SMartin Sebor 114884d7c60SMartin Sebor 11503b807d3SMartin Sebor; Do not fold strnlen(ax, n) == 0 for n that might be zero. 116884d7c60SMartin Sebor 11703b807d3SMartin Sebordefine i1 @call_strnlen_ax_n_eqz(i64 %n) { 118884d7c60SMartin Sebor; CHECK-LABEL: @call_strnlen_ax_n_eqz( 119*dc2b66b8SBjorn Pettersson; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(ptr nonnull @ax, i64 [[N:%.*]]) 120884d7c60SMartin Sebor; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0 121884d7c60SMartin Sebor; CHECK-NEXT: ret i1 [[EQZ]] 122884d7c60SMartin Sebor; 123884d7c60SMartin Sebor 124*dc2b66b8SBjorn Pettersson %len = tail call i64 @strnlen(ptr @ax, i64 %n) 125884d7c60SMartin Sebor %eqz = icmp eq i64 %len, 0 126884d7c60SMartin Sebor ret i1 %eqz 127884d7c60SMartin Sebor} 128884d7c60SMartin Sebor 129884d7c60SMartin Sebor 13003b807d3SMartin Sebor; Fold strnlen(ax, n) == 0 to *ax == 0 for %0 that's not zero. 131884d7c60SMartin Sebor 13203b807d3SMartin Sebordefine i1 @fold_strnlen_ax_nz_eqz(i64 %n) { 133884d7c60SMartin Sebor; CHECK-LABEL: @fold_strnlen_ax_nz_eqz( 134*dc2b66b8SBjorn Pettersson; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 1 135efa0f12cSMartin Sebor; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0 136884d7c60SMartin Sebor; CHECK-NEXT: ret i1 [[EQZ]] 137884d7c60SMartin Sebor; 138884d7c60SMartin Sebor 13903b807d3SMartin Sebor %max = or i64 %n, 1 140*dc2b66b8SBjorn Pettersson %len = tail call i64 @strnlen(ptr @ax, i64 %max) 141884d7c60SMartin Sebor %eqz = icmp eq i64 %len, 0 142884d7c60SMartin Sebor ret i1 %eqz 143884d7c60SMartin Sebor} 144884d7c60SMartin Sebor 145884d7c60SMartin Sebor 14603b807d3SMartin Sebor; Fold strnlen(ax, n) > 0 to *ax != 0 for n that's not zero. 147884d7c60SMartin Sebor 14803b807d3SMartin Sebordefine i1 @fold_strnlen_ax_nz_gtz(i64 %n) { 149884d7c60SMartin Sebor; CHECK-LABEL: @fold_strnlen_ax_nz_gtz( 150*dc2b66b8SBjorn Pettersson; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 1 151efa0f12cSMartin Sebor; CHECK-NEXT: [[GTZ:%.*]] = icmp ne i8 [[CHAR0]], 0 152884d7c60SMartin Sebor; CHECK-NEXT: ret i1 [[GTZ]] 153884d7c60SMartin Sebor; 154884d7c60SMartin Sebor 15503b807d3SMartin Sebor %max = or i64 %n, 1 156*dc2b66b8SBjorn Pettersson %len = tail call i64 @strnlen(ptr @ax, i64 %max) 157884d7c60SMartin Sebor %gtz = icmp ugt i64 %len, 0 158884d7c60SMartin Sebor ret i1 %gtz 159884d7c60SMartin Sebor} 160884d7c60SMartin Sebor 161884d7c60SMartin Sebor 16203b807d3SMartin Sebor; Fold strnlen(a5 + i, n) == 0 to a5[i] == 0 for a nonconstant a5 16303b807d3SMartin Sebor; and a nonzero n. 164884d7c60SMartin Sebor 16503b807d3SMartin Sebordefine i1 @fold_strnlen_a5_pi_nz_eqz(i64 %i, i64 %n) { 166884d7c60SMartin Sebor; CHECK-LABEL: @fold_strnlen_a5_pi_nz_eqz( 167*dc2b66b8SBjorn Pettersson; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [5 x i8], ptr @a5, i64 0, i64 [[I:%.*]] 168*dc2b66b8SBjorn Pettersson; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr [[PTR]], align 1 169efa0f12cSMartin Sebor; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0 170884d7c60SMartin Sebor; CHECK-NEXT: ret i1 [[EQZ]] 171884d7c60SMartin Sebor; 172884d7c60SMartin Sebor 17303b807d3SMartin Sebor %nz = or i64 %n, 1 174*dc2b66b8SBjorn Pettersson %ptr = getelementptr inbounds [5 x i8], ptr @a5, i64 0, i64 %i 175*dc2b66b8SBjorn Pettersson %len = call i64 @strnlen(ptr %ptr, i64 %nz) 176884d7c60SMartin Sebor %eqz = icmp eq i64 %len, 0 177884d7c60SMartin Sebor ret i1 %eqz 178884d7c60SMartin Sebor} 179884d7c60SMartin Sebor 180884d7c60SMartin Sebor 18103b807d3SMartin Sebor; Fold strnlen(s5 + i, n) == 0 for a constant s5 and nonzero n. 18203b807d3SMartin Sebor; This is first folded to s5[i] == 0 like the above and then finally 183884d7c60SMartin Sebor; to %0 == 5. 184884d7c60SMartin Sebor 18503b807d3SMartin Sebordefine i1 @fold_strnlen_s5_pi_nz_eqz(i64 %i, i64 %n) { 186884d7c60SMartin Sebor; CHECK-LABEL: @fold_strnlen_s5_pi_nz_eqz( 187efa0f12cSMartin Sebor; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[I:%.*]], 5 188bf38bdf7SMartin Sebor; CHECK-NEXT: ret i1 [[EQZ]] 189884d7c60SMartin Sebor; 190884d7c60SMartin Sebor 19103b807d3SMartin Sebor %nz = or i64 %n, 1 192*dc2b66b8SBjorn Pettersson %ptr = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 %i 193*dc2b66b8SBjorn Pettersson %len = call i64 @strnlen(ptr %ptr, i64 %nz) 19403b807d3SMartin Sebor %eqz = icmp eq i64 %len, 0 19503b807d3SMartin Sebor ret i1 %eqz 196884d7c60SMartin Sebor} 197884d7c60SMartin Sebor 198884d7c60SMartin Sebor 19903b807d3SMartin Sebor; Do not fold strnlen(s5 + i, n) for a constant s5 when n might be zero. 200884d7c60SMartin Sebor 20103b807d3SMartin Sebordefine i1 @call_strnlen_s5_pi_n_eqz(i64 %i, i64 %n) { 202884d7c60SMartin Sebor; CHECK-LABEL: @call_strnlen_s5_pi_n_eqz( 203*dc2b66b8SBjorn Pettersson; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 [[I:%.*]] 204*dc2b66b8SBjorn Pettersson; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr nonnull [[PTR]], i64 [[N:%.*]]) 205bf38bdf7SMartin Sebor; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0 206bf38bdf7SMartin Sebor; CHECK-NEXT: ret i1 [[EQZ]] 207884d7c60SMartin Sebor; 208884d7c60SMartin Sebor 209*dc2b66b8SBjorn Pettersson %ptr = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 %i 210*dc2b66b8SBjorn Pettersson %len = call i64 @strnlen(ptr %ptr, i64 %n) 21103b807d3SMartin Sebor %eqz = icmp eq i64 %len, 0 21203b807d3SMartin Sebor ret i1 %eqz 213884d7c60SMartin Sebor} 214