551 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes='loop-mssa(loop-predication)' -loop-predication-insert-assumes-of-predicated-guards-conditions=false < %s 2>&1 | FileCheck %s3 4define i32 @test_ult(ptr noundef %p, i32 noundef %n, ptr noundef %arr, ptr noundef %len_p, i32 noundef %c) {5; CHECK-LABEL: @test_ult(6; CHECK-NEXT: entry:7; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[LEN_P:%.*]], align 4, !range [[RNG0:![0-9]+]], !noundef !18; CHECK-NEXT: br label [[LOOP:%.*]]9; CHECK: loop:10; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]11; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]12; CHECK-NEXT: [[EL:%.*]] = load i32, ptr [[EL_PTR]], align 413; CHECK-NEXT: [[BOUND_CHECK:%.*]] = icmp ult i32 [[EL]], 12814; CHECK-NEXT: br i1 [[BOUND_CHECK]], label [[DO_RANGE_CHECK:%.*]], label [[BOUND_CHECK_FAILED:%.*]]15; CHECK: do_range_check:16; CHECK-NEXT: call void @llvm.assume(i1 [[BOUND_CHECK]])17; CHECK-NEXT: [[RANGE_CHECK_ULT:%.*]] = icmp ult i32 [[EL]], [[LEN]]18; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()19; CHECK-NEXT: [[EXPLICIT_GUARD_COND:%.*]] = and i1 [[RANGE_CHECK_ULT]], [[WC]]20; CHECK-NEXT: br i1 [[EXPLICIT_GUARD_COND]], label [[BACKEDGE]], label [[DEOPT:%.*]]21; CHECK: backedge:22; CHECK-NEXT: [[ARR_PTR:%.*]] = getelementptr i32, ptr [[ARR:%.*]], i32 [[EL]]23; CHECK-NEXT: store i32 [[IV]], ptr [[ARR_PTR]], align 424; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 125; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[N:%.*]]26; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]27; CHECK: deopt:28; CHECK-NEXT: [[DEOPT_RES:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]29; CHECK-NEXT: ret i32 [[DEOPT_RES]]30; CHECK: exit:31; CHECK-NEXT: ret i32 032; CHECK: bound_check_failed:33; CHECK-NEXT: ret i32 -134;35entry:36 %len = load i32, ptr %len_p, align 4, !noundef !0, !range !137 br label %loop38 39loop:40 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]41 %el.ptr = getelementptr i32, ptr %p, i32 %iv42 %el = load i32, ptr %el.ptr, align 443 %bound_check = icmp ult i32 %el, 12844 br i1 %bound_check, label %do_range_check, label %bound_check_failed45 46do_range_check:47 call void @llvm.assume(i1 %bound_check)48 %range_check.ult = icmp ult i32 %el, %len49 %wc = call i1 @llvm.experimental.widenable.condition()50 %explicit_guard_cond = and i1 %range_check.ult, %wc51 br i1 %explicit_guard_cond, label %backedge, label %deopt52 53backedge:54 %arr.ptr = getelementptr i32, ptr %arr, i32 %el55 store i32 %iv, ptr %arr.ptr, align 456 %iv.next = add i32 %iv, 157 %loop_cond = icmp slt i32 %iv.next, %n58 br i1 %loop_cond, label %loop, label %exit59 60deopt:61 %deopt_res = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]62 ret i32 %deopt_res63 64exit:65 ret i32 066 67bound_check_failed:68 ret i32 -169}70 71define i32 @test_slt(ptr noundef %p, i32 noundef %n, ptr noundef %arr, ptr noundef %len_p, i32 noundef %c) {72; CHECK-LABEL: @test_slt(73; CHECK-NEXT: entry:74; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[LEN_P:%.*]], align 4, !range [[RNG0]], !noundef !175; CHECK-NEXT: br label [[LOOP:%.*]]76; CHECK: loop:77; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]78; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]79; CHECK-NEXT: [[EL:%.*]] = load i32, ptr [[EL_PTR]], align 480; CHECK-NEXT: [[BOUND_CHECK:%.*]] = icmp slt i32 [[EL]], 12881; CHECK-NEXT: br i1 [[BOUND_CHECK]], label [[DO_RANGE_CHECK:%.*]], label [[BOUND_CHECK_FAILED:%.*]]82; CHECK: do_range_check:83; CHECK-NEXT: call void @llvm.assume(i1 [[BOUND_CHECK]])84; CHECK-NEXT: [[RANGE_CHECK_SLT:%.*]] = icmp slt i32 [[EL]], [[LEN]]85; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()86; CHECK-NEXT: [[EXPLICIT_GUARD_COND:%.*]] = and i1 [[RANGE_CHECK_SLT]], [[WC]]87; CHECK-NEXT: br i1 [[EXPLICIT_GUARD_COND]], label [[BACKEDGE]], label [[DEOPT:%.*]]88; CHECK: backedge:89; CHECK-NEXT: [[ARR_PTR:%.*]] = getelementptr i32, ptr [[ARR:%.*]], i32 [[EL]]90; CHECK-NEXT: store i32 [[IV]], ptr [[ARR_PTR]], align 491; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 192; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[N:%.*]]93; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]94; CHECK: deopt:95; CHECK-NEXT: [[DEOPT_RES:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]96; CHECK-NEXT: ret i32 [[DEOPT_RES]]97; CHECK: exit:98; CHECK-NEXT: ret i32 099; CHECK: bound_check_failed:100; CHECK-NEXT: ret i32 -1101;102entry:103 %len = load i32, ptr %len_p, align 4, !noundef !0, !range !1104 br label %loop105 106loop:107 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]108 %el.ptr = getelementptr i32, ptr %p, i32 %iv109 %el = load i32, ptr %el.ptr, align 4110 %bound_check = icmp slt i32 %el, 128111 br i1 %bound_check, label %do_range_check, label %bound_check_failed112 113do_range_check:114 call void @llvm.assume(i1 %bound_check)115 %range_check.slt = icmp slt i32 %el, %len116 %wc = call i1 @llvm.experimental.widenable.condition()117 %explicit_guard_cond = and i1 %range_check.slt, %wc118 br i1 %explicit_guard_cond, label %backedge, label %deopt119 120backedge:121 %arr.ptr = getelementptr i32, ptr %arr, i32 %el122 store i32 %iv, ptr %arr.ptr, align 4123 %iv.next = add i32 %iv, 1124 %loop_cond = icmp ult i32 %iv.next, %n125 br i1 %loop_cond, label %loop, label %exit126 127deopt:128 %deopt_res = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]129 ret i32 %deopt_res130 131exit:132 ret i32 0133 134bound_check_failed:135 ret i32 -1136}137 138define i32 @test_ule(ptr noundef %p, i32 noundef %n, ptr noundef %arr, ptr noundef %len_p, i32 noundef %c) {139; CHECK-LABEL: @test_ule(140; CHECK-NEXT: entry:141; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[LEN_P:%.*]], align 4, !range [[RNG0]], !noundef !1142; CHECK-NEXT: br label [[LOOP:%.*]]143; CHECK: loop:144; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]145; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]146; CHECK-NEXT: [[EL:%.*]] = load i32, ptr [[EL_PTR]], align 4147; CHECK-NEXT: [[BOUND_CHECK:%.*]] = icmp ult i32 [[EL]], 128148; CHECK-NEXT: br i1 [[BOUND_CHECK]], label [[DO_RANGE_CHECK:%.*]], label [[BOUND_CHECK_FAILED:%.*]]149; CHECK: do_range_check:150; CHECK-NEXT: call void @llvm.assume(i1 [[BOUND_CHECK]])151; CHECK-NEXT: [[RANGE_CHECK_ULE:%.*]] = icmp ule i32 [[EL]], [[LEN]]152; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()153; CHECK-NEXT: [[EXPLICIT_GUARD_COND:%.*]] = and i1 [[RANGE_CHECK_ULE]], [[WC]]154; CHECK-NEXT: br i1 [[EXPLICIT_GUARD_COND]], label [[BACKEDGE]], label [[DEOPT:%.*]]155; CHECK: backedge:156; CHECK-NEXT: [[ARR_PTR:%.*]] = getelementptr i32, ptr [[ARR:%.*]], i32 [[EL]]157; CHECK-NEXT: store i32 [[IV]], ptr [[ARR_PTR]], align 4158; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1159; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[N:%.*]]160; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]161; CHECK: deopt:162; CHECK-NEXT: [[DEOPT_RES:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]163; CHECK-NEXT: ret i32 [[DEOPT_RES]]164; CHECK: exit:165; CHECK-NEXT: ret i32 0166; CHECK: bound_check_failed:167; CHECK-NEXT: ret i32 -1168;169entry:170 %len = load i32, ptr %len_p, align 4, !noundef !0, !range !1171 br label %loop172 173loop:174 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]175 %el.ptr = getelementptr i32, ptr %p, i32 %iv176 %el = load i32, ptr %el.ptr, align 4177 %bound_check = icmp ult i32 %el, 128178 br i1 %bound_check, label %do_range_check, label %bound_check_failed179 180do_range_check:181 call void @llvm.assume(i1 %bound_check)182 %range_check.ule = icmp ule i32 %el, %len183 %wc = call i1 @llvm.experimental.widenable.condition()184 %explicit_guard_cond = and i1 %range_check.ule, %wc185 br i1 %explicit_guard_cond, label %backedge, label %deopt186 187backedge:188 %arr.ptr = getelementptr i32, ptr %arr, i32 %el189 store i32 %iv, ptr %arr.ptr, align 4190 %iv.next = add i32 %iv, 1191 %loop_cond = icmp ult i32 %iv.next, %n192 br i1 %loop_cond, label %loop, label %exit193 194deopt:195 %deopt_res = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]196 ret i32 %deopt_res197 198exit:199 ret i32 0200 201bound_check_failed:202 ret i32 -1203}204 205define i32 @test_sle(ptr noundef %p, i32 noundef %n, ptr noundef %arr, ptr noundef %len_p, i32 noundef %c) {206; CHECK-LABEL: @test_sle(207; CHECK-NEXT: entry:208; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[LEN_P:%.*]], align 4, !range [[RNG0]], !noundef !1209; CHECK-NEXT: br label [[LOOP:%.*]]210; CHECK: loop:211; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]212; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]213; CHECK-NEXT: [[EL:%.*]] = load i32, ptr [[EL_PTR]], align 4214; CHECK-NEXT: [[BOUND_CHECK:%.*]] = icmp slt i32 [[EL]], 128215; CHECK-NEXT: br i1 [[BOUND_CHECK]], label [[DO_RANGE_CHECK:%.*]], label [[BOUND_CHECK_FAILED:%.*]]216; CHECK: do_range_check:217; CHECK-NEXT: call void @llvm.assume(i1 [[BOUND_CHECK]])218; CHECK-NEXT: [[RANGE_CHECK_SLE:%.*]] = icmp sle i32 [[EL]], [[LEN]]219; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()220; CHECK-NEXT: [[EXPLICIT_GUARD_COND:%.*]] = and i1 [[RANGE_CHECK_SLE]], [[WC]]221; CHECK-NEXT: br i1 [[EXPLICIT_GUARD_COND]], label [[BACKEDGE]], label [[DEOPT:%.*]]222; CHECK: backedge:223; CHECK-NEXT: [[ARR_PTR:%.*]] = getelementptr i32, ptr [[ARR:%.*]], i32 [[EL]]224; CHECK-NEXT: store i32 [[IV]], ptr [[ARR_PTR]], align 4225; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1226; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[N:%.*]]227; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]228; CHECK: deopt:229; CHECK-NEXT: [[DEOPT_RES:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]230; CHECK-NEXT: ret i32 [[DEOPT_RES]]231; CHECK: exit:232; CHECK-NEXT: ret i32 0233; CHECK: bound_check_failed:234; CHECK-NEXT: ret i32 -1235;236entry:237 %len = load i32, ptr %len_p, align 4, !noundef !0, !range !1238 br label %loop239 240loop:241 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]242 %el.ptr = getelementptr i32, ptr %p, i32 %iv243 %el = load i32, ptr %el.ptr, align 4244 %bound_check = icmp slt i32 %el, 128245 br i1 %bound_check, label %do_range_check, label %bound_check_failed246 247do_range_check:248 call void @llvm.assume(i1 %bound_check)249 %range_check.sle = icmp sle i32 %el, %len250 %wc = call i1 @llvm.experimental.widenable.condition()251 %explicit_guard_cond = and i1 %range_check.sle, %wc252 br i1 %explicit_guard_cond, label %backedge, label %deopt253 254backedge:255 %arr.ptr = getelementptr i32, ptr %arr, i32 %el256 store i32 %iv, ptr %arr.ptr, align 4257 %iv.next = add i32 %iv, 1258 %loop_cond = icmp ult i32 %iv.next, %n259 br i1 %loop_cond, label %loop, label %exit260 261deopt:262 %deopt_res = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]263 ret i32 %deopt_res264 265exit:266 ret i32 0267 268bound_check_failed:269 ret i32 -1270}271 272define i32 @test_ugt(ptr noundef %p, i32 noundef %n, ptr noundef %arr, ptr noundef %len_p, i32 noundef %c) {273; CHECK-LABEL: @test_ugt(274; CHECK-NEXT: entry:275; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[LEN_P:%.*]], align 4, !range [[RNG0]], !noundef !1276; CHECK-NEXT: br label [[LOOP:%.*]]277; CHECK: loop:278; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]279; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]280; CHECK-NEXT: [[EL:%.*]] = load i32, ptr [[EL_PTR]], align 4281; CHECK-NEXT: [[BOUND_CHECK:%.*]] = icmp ult i32 [[EL]], 128282; CHECK-NEXT: br i1 [[BOUND_CHECK]], label [[DO_RANGE_CHECK:%.*]], label [[BOUND_CHECK_FAILED:%.*]]283; CHECK: do_range_check:284; CHECK-NEXT: call void @llvm.assume(i1 [[BOUND_CHECK]])285; CHECK-NEXT: [[RANGE_CHECK_SLE:%.*]] = icmp ugt i32 [[LEN]], [[EL]]286; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()287; CHECK-NEXT: [[EXPLICIT_GUARD_COND:%.*]] = and i1 [[RANGE_CHECK_SLE]], [[WC]]288; CHECK-NEXT: br i1 [[EXPLICIT_GUARD_COND]], label [[BACKEDGE]], label [[DEOPT:%.*]]289; CHECK: backedge:290; CHECK-NEXT: [[ARR_PTR:%.*]] = getelementptr i32, ptr [[ARR:%.*]], i32 [[EL]]291; CHECK-NEXT: store i32 [[IV]], ptr [[ARR_PTR]], align 4292; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1293; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[N:%.*]]294; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]295; CHECK: deopt:296; CHECK-NEXT: [[DEOPT_RES:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]297; CHECK-NEXT: ret i32 [[DEOPT_RES]]298; CHECK: exit:299; CHECK-NEXT: ret i32 0300; CHECK: bound_check_failed:301; CHECK-NEXT: ret i32 -1302;303entry:304 %len = load i32, ptr %len_p, align 4, !noundef !0, !range !1305 br label %loop306 307loop:308 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]309 %el.ptr = getelementptr i32, ptr %p, i32 %iv310 %el = load i32, ptr %el.ptr, align 4311 %bound_check = icmp ult i32 %el, 128312 br i1 %bound_check, label %do_range_check, label %bound_check_failed313 314do_range_check:315 call void @llvm.assume(i1 %bound_check)316 %range_check.sle = icmp ugt i32 %len, %el317 %wc = call i1 @llvm.experimental.widenable.condition()318 %explicit_guard_cond = and i1 %range_check.sle, %wc319 br i1 %explicit_guard_cond, label %backedge, label %deopt320 321backedge:322 %arr.ptr = getelementptr i32, ptr %arr, i32 %el323 store i32 %iv, ptr %arr.ptr, align 4324 %iv.next = add i32 %iv, 1325 %loop_cond = icmp ult i32 %iv.next, %n326 br i1 %loop_cond, label %loop, label %exit327 328deopt:329 %deopt_res = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]330 ret i32 %deopt_res331 332exit:333 ret i32 0334 335bound_check_failed:336 ret i32 -1337}338 339define i32 @test_uge(ptr noundef %p, i32 noundef %n, ptr noundef %arr, ptr noundef %len_p, i32 noundef %c) {340; CHECK-LABEL: @test_uge(341; CHECK-NEXT: entry:342; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[LEN_P:%.*]], align 4, !range [[RNG0]], !noundef !1343; CHECK-NEXT: br label [[LOOP:%.*]]344; CHECK: loop:345; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]346; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]347; CHECK-NEXT: [[EL:%.*]] = load i32, ptr [[EL_PTR]], align 4348; CHECK-NEXT: [[BOUND_CHECK:%.*]] = icmp ult i32 [[EL]], 128349; CHECK-NEXT: br i1 [[BOUND_CHECK]], label [[DO_RANGE_CHECK:%.*]], label [[BOUND_CHECK_FAILED:%.*]]350; CHECK: do_range_check:351; CHECK-NEXT: call void @llvm.assume(i1 [[BOUND_CHECK]])352; CHECK-NEXT: [[RANGE_CHECK_SLE:%.*]] = icmp uge i32 [[LEN]], [[EL]]353; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()354; CHECK-NEXT: [[EXPLICIT_GUARD_COND:%.*]] = and i1 [[RANGE_CHECK_SLE]], [[WC]]355; CHECK-NEXT: br i1 [[EXPLICIT_GUARD_COND]], label [[BACKEDGE]], label [[DEOPT:%.*]]356; CHECK: backedge:357; CHECK-NEXT: [[ARR_PTR:%.*]] = getelementptr i32, ptr [[ARR:%.*]], i32 [[EL]]358; CHECK-NEXT: store i32 [[IV]], ptr [[ARR_PTR]], align 4359; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1360; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[N:%.*]]361; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]362; CHECK: deopt:363; CHECK-NEXT: [[DEOPT_RES:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]364; CHECK-NEXT: ret i32 [[DEOPT_RES]]365; CHECK: exit:366; CHECK-NEXT: ret i32 0367; CHECK: bound_check_failed:368; CHECK-NEXT: ret i32 -1369;370entry:371 %len = load i32, ptr %len_p, align 4, !noundef !0, !range !1372 br label %loop373 374loop:375 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]376 %el.ptr = getelementptr i32, ptr %p, i32 %iv377 %el = load i32, ptr %el.ptr, align 4378 %bound_check = icmp ult i32 %el, 128379 br i1 %bound_check, label %do_range_check, label %bound_check_failed380 381do_range_check:382 call void @llvm.assume(i1 %bound_check)383 %range_check.sle = icmp uge i32 %len, %el384 %wc = call i1 @llvm.experimental.widenable.condition()385 %explicit_guard_cond = and i1 %range_check.sle, %wc386 br i1 %explicit_guard_cond, label %backedge, label %deopt387 388backedge:389 %arr.ptr = getelementptr i32, ptr %arr, i32 %el390 store i32 %iv, ptr %arr.ptr, align 4391 %iv.next = add i32 %iv, 1392 %loop_cond = icmp ult i32 %iv.next, %n393 br i1 %loop_cond, label %loop, label %exit394 395deopt:396 %deopt_res = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]397 ret i32 %deopt_res398 399exit:400 ret i32 0401 402bound_check_failed:403 ret i32 -1404}405 406define i32 @test_sgt(ptr noundef %p, i32 noundef %n, ptr noundef %arr, ptr noundef %len_p, i32 noundef %c) {407; CHECK-LABEL: @test_sgt(408; CHECK-NEXT: entry:409; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[LEN_P:%.*]], align 4, !range [[RNG0]], !noundef !1410; CHECK-NEXT: br label [[LOOP:%.*]]411; CHECK: loop:412; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]413; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]414; CHECK-NEXT: [[EL:%.*]] = load i32, ptr [[EL_PTR]], align 4415; CHECK-NEXT: [[BOUND_CHECK:%.*]] = icmp slt i32 [[EL]], 128416; CHECK-NEXT: br i1 [[BOUND_CHECK]], label [[DO_RANGE_CHECK:%.*]], label [[BOUND_CHECK_FAILED:%.*]]417; CHECK: do_range_check:418; CHECK-NEXT: call void @llvm.assume(i1 [[BOUND_CHECK]])419; CHECK-NEXT: [[RANGE_CHECK_SLE:%.*]] = icmp sgt i32 [[LEN]], [[EL]]420; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()421; CHECK-NEXT: [[EXPLICIT_GUARD_COND:%.*]] = and i1 [[RANGE_CHECK_SLE]], [[WC]]422; CHECK-NEXT: br i1 [[EXPLICIT_GUARD_COND]], label [[BACKEDGE]], label [[DEOPT:%.*]]423; CHECK: backedge:424; CHECK-NEXT: [[ARR_PTR:%.*]] = getelementptr i32, ptr [[ARR:%.*]], i32 [[EL]]425; CHECK-NEXT: store i32 [[IV]], ptr [[ARR_PTR]], align 4426; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1427; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[N:%.*]]428; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]429; CHECK: deopt:430; CHECK-NEXT: [[DEOPT_RES:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]431; CHECK-NEXT: ret i32 [[DEOPT_RES]]432; CHECK: exit:433; CHECK-NEXT: ret i32 0434; CHECK: bound_check_failed:435; CHECK-NEXT: ret i32 -1436;437entry:438 %len = load i32, ptr %len_p, align 4, !noundef !0, !range !1439 br label %loop440 441loop:442 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]443 %el.ptr = getelementptr i32, ptr %p, i32 %iv444 %el = load i32, ptr %el.ptr, align 4445 %bound_check = icmp slt i32 %el, 128446 br i1 %bound_check, label %do_range_check, label %bound_check_failed447 448do_range_check:449 call void @llvm.assume(i1 %bound_check)450 %range_check.sle = icmp sgt i32 %len, %el451 %wc = call i1 @llvm.experimental.widenable.condition()452 %explicit_guard_cond = and i1 %range_check.sle, %wc453 br i1 %explicit_guard_cond, label %backedge, label %deopt454 455backedge:456 %arr.ptr = getelementptr i32, ptr %arr, i32 %el457 store i32 %iv, ptr %arr.ptr, align 4458 %iv.next = add i32 %iv, 1459 %loop_cond = icmp ult i32 %iv.next, %n460 br i1 %loop_cond, label %loop, label %exit461 462deopt:463 %deopt_res = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]464 ret i32 %deopt_res465 466exit:467 ret i32 0468 469bound_check_failed:470 ret i32 -1471}472 473define i32 @test_sge(ptr noundef %p, i32 noundef %n, ptr noundef %arr, ptr noundef %len_p, i32 noundef %c) {474; CHECK-LABEL: @test_sge(475; CHECK-NEXT: entry:476; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[LEN_P:%.*]], align 4, !range [[RNG0]], !noundef !1477; CHECK-NEXT: br label [[LOOP:%.*]]478; CHECK: loop:479; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]480; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]481; CHECK-NEXT: [[EL:%.*]] = load i32, ptr [[EL_PTR]], align 4482; CHECK-NEXT: [[BOUND_CHECK:%.*]] = icmp slt i32 [[EL]], 128483; CHECK-NEXT: br i1 [[BOUND_CHECK]], label [[DO_RANGE_CHECK:%.*]], label [[BOUND_CHECK_FAILED:%.*]]484; CHECK: do_range_check:485; CHECK-NEXT: call void @llvm.assume(i1 [[BOUND_CHECK]])486; CHECK-NEXT: [[RANGE_CHECK_SLE:%.*]] = icmp sge i32 [[LEN]], [[EL]]487; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()488; CHECK-NEXT: [[EXPLICIT_GUARD_COND:%.*]] = and i1 [[RANGE_CHECK_SLE]], [[WC]]489; CHECK-NEXT: br i1 [[EXPLICIT_GUARD_COND]], label [[BACKEDGE]], label [[DEOPT:%.*]]490; CHECK: backedge:491; CHECK-NEXT: [[ARR_PTR:%.*]] = getelementptr i32, ptr [[ARR:%.*]], i32 [[EL]]492; CHECK-NEXT: store i32 [[IV]], ptr [[ARR_PTR]], align 4493; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1494; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], [[N:%.*]]495; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]496; CHECK: deopt:497; CHECK-NEXT: [[DEOPT_RES:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]498; CHECK-NEXT: ret i32 [[DEOPT_RES]]499; CHECK: exit:500; CHECK-NEXT: ret i32 0501; CHECK: bound_check_failed:502; CHECK-NEXT: ret i32 -1503;504entry:505 %len = load i32, ptr %len_p, align 4, !noundef !0, !range !1506 br label %loop507 508loop:509 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]510 %el.ptr = getelementptr i32, ptr %p, i32 %iv511 %el = load i32, ptr %el.ptr, align 4512 %bound_check = icmp slt i32 %el, 128513 br i1 %bound_check, label %do_range_check, label %bound_check_failed514 515do_range_check:516 call void @llvm.assume(i1 %bound_check)517 %range_check.sle = icmp sge i32 %len, %el518 %wc = call i1 @llvm.experimental.widenable.condition()519 %explicit_guard_cond = and i1 %range_check.sle, %wc520 br i1 %explicit_guard_cond, label %backedge, label %deopt521 522backedge:523 %arr.ptr = getelementptr i32, ptr %arr, i32 %el524 store i32 %iv, ptr %arr.ptr, align 4525 %iv.next = add i32 %iv, 1526 %loop_cond = icmp ult i32 %iv.next, %n527 br i1 %loop_cond, label %loop, label %exit528 529deopt:530 %deopt_res = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]531 ret i32 %deopt_res532 533exit:534 ret i32 0535 536bound_check_failed:537 ret i32 -1538}539 540; Function Attrs: inaccessiblememonly nocallback nofree nosync nounwind speculatable willreturn541declare i1 @llvm.experimental.widenable.condition() #1542 543declare i32 @llvm.experimental.deoptimize.i32(...)544 545declare void @llvm.assume(i1)546 547attributes #1 = { inaccessiblememonly nocallback nofree nosync nounwind speculatable willreturn }548 549!0 = !{}550!1 = !{i32 0, i32 2147483646}551