374 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=guard-widening < %s | FileCheck %s3 4declare void @llvm.experimental.guard(i1,...)5 6define void @f_0(i32 %x, ptr %length_buf) {7; CHECK-LABEL: @f_0(8; CHECK-NEXT: entry:9; CHECK-NEXT: [[X_GW_FR:%.*]] = freeze i32 [[X:%.*]]10; CHECK-NEXT: [[LENGTH:%.*]] = load i32, ptr [[LENGTH_BUF:%.*]], align 4, !range [[RNG0:![0-9]+]], !noundef !111; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X_GW_FR]], [[LENGTH]]12; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X_GW_FR]], 113; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]14; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]15; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X_GW_FR]], 216; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]17; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK2]], [[CHK0]]18; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X_GW_FR]], 319; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]20; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK3]], [[CHK0]]21; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]22; CHECK-NEXT: ret void23;24entry:25 %length = load i32, ptr %length_buf, !range !0, !noundef !{}26 %chk0 = icmp ult i32 %x, %length27 call void(i1, ...) @llvm.experimental.guard(i1 %chk0) [ "deopt"() ]28 29 %x.inc1 = add i32 %x, 130 %chk1 = icmp ult i32 %x.inc1, %length31 call void(i1, ...) @llvm.experimental.guard(i1 %chk1) [ "deopt"() ]32 33 %x.inc2 = add i32 %x, 234 %chk2 = icmp ult i32 %x.inc2, %length35 call void(i1, ...) @llvm.experimental.guard(i1 %chk2) [ "deopt"() ]36 37 %x.inc3 = add i32 %x, 338 %chk3 = icmp ult i32 %x.inc3, %length39 call void(i1, ...) @llvm.experimental.guard(i1 %chk3) [ "deopt"() ]40 ret void41}42 43define void @f_1(i32 %x, ptr %length_buf) {44; CHECK-LABEL: @f_1(45; CHECK-NEXT: entry:46; CHECK-NEXT: [[X_GW_FR:%.*]] = freeze i32 [[X:%.*]]47; CHECK-NEXT: [[LENGTH:%.*]] = load i32, ptr [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]], !noundef !148; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X_GW_FR]], [[LENGTH]]49; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X_GW_FR]], 150; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]51; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]52; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X_INC1]], 253; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]54; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK2]], [[CHK0]]55; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X_INC2]], 356; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]57; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK3]], [[CHK0]]58; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]59; CHECK-NEXT: ret void60;61entry:62 %length = load i32, ptr %length_buf, !range !0, !noundef !{}63 %chk0 = icmp ult i32 %x, %length64 call void(i1, ...) @llvm.experimental.guard(i1 %chk0) [ "deopt"() ]65 66 %x.inc1 = add i32 %x, 167 %chk1 = icmp ult i32 %x.inc1, %length68 call void(i1, ...) @llvm.experimental.guard(i1 %chk1) [ "deopt"() ]69 70 %x.inc2 = add i32 %x.inc1, 271 %chk2 = icmp ult i32 %x.inc2, %length72 call void(i1, ...) @llvm.experimental.guard(i1 %chk2) [ "deopt"() ]73 74 %x.inc3 = add i32 %x.inc2, 375 %chk3 = icmp ult i32 %x.inc3, %length76 call void(i1, ...) @llvm.experimental.guard(i1 %chk3) [ "deopt"() ]77 ret void78}79 80define void @f_2(i32 %a, ptr %length_buf) {81; CHECK-LABEL: @f_2(82; CHECK-NEXT: entry:83; CHECK-NEXT: [[A_GW_FR:%.*]] = freeze i32 [[A:%.*]]84; CHECK-NEXT: [[X:%.*]] = and i32 [[A_GW_FR]], -25685; CHECK-NEXT: [[LENGTH:%.*]] = load i32, ptr [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]]86; CHECK-NEXT: [[LENGTH_GW_FR:%.*]] = freeze i32 [[LENGTH]]87; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X]], [[LENGTH_GW_FR]]88; CHECK-NEXT: [[X_INC1:%.*]] = or i32 [[X]], 189; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH_GW_FR]]90; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]91; CHECK-NEXT: [[X_INC2:%.*]] = or i32 [[X]], 292; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH_GW_FR]]93; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[CHK2]]94; CHECK-NEXT: [[X_INC3:%.*]] = or i32 [[X]], 395; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH_GW_FR]]96; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[WIDE_CHK1]], [[CHK3]]97; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]98; CHECK-NEXT: ret void99;100entry:101 %x = and i32 %a, 4294967040 ;; 4294967040 == 0xffffff00102 %length = load i32, ptr %length_buf, !range !0103 %chk0 = icmp ult i32 %x, %length104 call void(i1, ...) @llvm.experimental.guard(i1 %chk0) [ "deopt"() ]105 106 %x.inc1 = or i32 %x, 1107 %chk1 = icmp ult i32 %x.inc1, %length108 call void(i1, ...) @llvm.experimental.guard(i1 %chk1) [ "deopt"() ]109 110 %x.inc2 = or i32 %x, 2111 %chk2 = icmp ult i32 %x.inc2, %length112 call void(i1, ...) @llvm.experimental.guard(i1 %chk2) [ "deopt"() ]113 114 %x.inc3 = or i32 %x, 3115 %chk3 = icmp ult i32 %x.inc3, %length116 call void(i1, ...) @llvm.experimental.guard(i1 %chk3) [ "deopt"() ]117 ret void118}119 120define void @f_3(i32 %a, ptr %length_buf) {121; CHECK-LABEL: @f_3(122; CHECK-NEXT: entry:123; CHECK-NEXT: [[A_GW_FR:%.*]] = freeze i32 [[A:%.*]]124; CHECK-NEXT: [[X:%.*]] = and i32 [[A_GW_FR]], -256125; CHECK-NEXT: [[LENGTH:%.*]] = load i32, ptr [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]], !noundef !1126; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X]], [[LENGTH]]127; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X]], 1128; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]129; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]130; CHECK-NEXT: [[X_INC2:%.*]] = or i32 [[X_INC1]], 2131; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]132; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK2]], [[CHK0]]133; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X_INC2]], 3134; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]135; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK3]], [[CHK0]]136; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]137; CHECK-NEXT: ret void138;139entry:140 %x = and i32 %a, 4294967040 ;; 4294967040 == 0xffffff00141 %length = load i32, ptr %length_buf, !range !0, !noundef !{}142 %chk0 = icmp ult i32 %x, %length143 call void(i1, ...) @llvm.experimental.guard(i1 %chk0) [ "deopt"() ]144 145 %x.inc1 = add i32 %x, 1146 %chk1 = icmp ult i32 %x.inc1, %length147 call void(i1, ...) @llvm.experimental.guard(i1 %chk1) [ "deopt"() ]148 149 %x.inc2 = or i32 %x.inc1, 2150 %chk2 = icmp ult i32 %x.inc2, %length151 call void(i1, ...) @llvm.experimental.guard(i1 %chk2) [ "deopt"() ]152 153 %x.inc3 = add i32 %x.inc2, 3154 %chk3 = icmp ult i32 %x.inc3, %length155 call void(i1, ...) @llvm.experimental.guard(i1 %chk3) [ "deopt"() ]156 ret void157}158 159define void @f_4(i32 %x, ptr %length_buf) {160; CHECK-LABEL: @f_4(161; CHECK-NEXT: entry:162; CHECK-NEXT: [[X_GW_FR:%.*]] = freeze i32 [[X:%.*]]163; CHECK-NEXT: [[LENGTH:%.*]] = load i32, ptr [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]], !noundef !1164; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X_GW_FR]], [[LENGTH]]165; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X_GW_FR]], -1024166; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]167; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]168; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X_GW_FR]], 2169; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]170; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK2]], [[CHK1]]171; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X_GW_FR]], 3172; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]173; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK3]], [[CHK1]]174; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]175; CHECK-NEXT: ret void176;177 178; Note: we NOT guarding on "and i1 %chk3, %chk0", that would be incorrect.179entry:180 %length = load i32, ptr %length_buf, !range !0, !noundef !{}181 %chk0 = icmp ult i32 %x, %length182 call void(i1, ...) @llvm.experimental.guard(i1 %chk0) [ "deopt"() ]183 184 %x.inc1 = add i32 %x, -1024185 %chk1 = icmp ult i32 %x.inc1, %length186 call void(i1, ...) @llvm.experimental.guard(i1 %chk1) [ "deopt"() ]187 188 %x.inc2 = add i32 %x, 2189 %chk2 = icmp ult i32 %x.inc2, %length190 call void(i1, ...) @llvm.experimental.guard(i1 %chk2) [ "deopt"() ]191 192 %x.inc3 = add i32 %x, 3193 %chk3 = icmp ult i32 %x.inc3, %length194 call void(i1, ...) @llvm.experimental.guard(i1 %chk3) [ "deopt"() ]195 ret void196}197 198define void @f_5(i32 %x, ptr %length_buf) {199; CHECK-LABEL: @f_5(200; CHECK-NEXT: entry:201; CHECK-NEXT: [[X_GW_FR:%.*]] = freeze i32 [[X:%.*]]202; CHECK-NEXT: [[LENGTH:%.*]] = load i32, ptr [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]], !noundef !1203; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X_GW_FR]], [[LENGTH]]204; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X_GW_FR]], 1205; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]206; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]207; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X_INC1]], -200208; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]209; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK1]], [[CHK2]]210; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK1]], [[CHK2]]211; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]212; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X_INC2]], 3213; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]214; CHECK-NEXT: ret void215;216entry:217 %length = load i32, ptr %length_buf, !range !0, !noundef !{}218 %chk0 = icmp ult i32 %x, %length219 call void(i1, ...) @llvm.experimental.guard(i1 %chk0) [ "deopt"() ]220 221 %x.inc1 = add i32 %x, 1222 %chk1 = icmp ult i32 %x.inc1, %length223 call void(i1, ...) @llvm.experimental.guard(i1 %chk1) [ "deopt"() ]224 225 %x.inc2 = add i32 %x.inc1, -200226 %chk2 = icmp ult i32 %x.inc2, %length227 call void(i1, ...) @llvm.experimental.guard(i1 %chk2) [ "deopt"() ]228 229 %x.inc3 = add i32 %x.inc2, 3230 %chk3 = icmp ult i32 %x.inc3, %length231 call void(i1, ...) @llvm.experimental.guard(i1 %chk3) [ "deopt"() ]232 ret void233}234 235 236; Negative test: we can't merge these checks into237;238; (%x + -2147483647) u< L && (%x + 3) u< L239;240; because if %length == INT_MAX and %x == -3 then241;242; (%x + -2147483647) == i32 2147483646 u< L (L is 2147483647)243; (%x + 3) == 0 u< L244;245; But (%x + 2) == -1 is not u< L246;247define void @f_6(i32 %x, ptr %length_buf) {248; CHECK-LABEL: @f_6(249; CHECK-NEXT: entry:250; CHECK-NEXT: [[X_GW_FR:%.*]] = freeze i32 [[X:%.*]]251; CHECK-NEXT: [[LENGTH:%.*]] = load i32, ptr [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]], !noundef !1252; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X_GW_FR]], [[LENGTH]]253; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X_GW_FR]], -2147483647254; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]255; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]256; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X_GW_FR]], 2257; CHECK-NEXT: [[CHK2:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH]]258; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[CHK2]]259; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X_GW_FR]], 3260; CHECK-NEXT: [[CHK3:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH]]261; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[WIDE_CHK1]], [[CHK3]]262; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]263; CHECK-NEXT: ret void264;265entry:266 %length = load i32, ptr %length_buf, !range !0, !noundef !{}267 %chk0 = icmp ult i32 %x, %length268 call void(i1, ...) @llvm.experimental.guard(i1 %chk0) [ "deopt"() ]269 270 %x.inc1 = add i32 %x, -2147483647 ;; -2147483647 == (i32 INT_MIN)+1 == -(i32 INT_MAX)271 %chk1 = icmp ult i32 %x.inc1, %length272 call void(i1, ...) @llvm.experimental.guard(i1 %chk1) [ "deopt"() ]273 274 %x.inc2 = add i32 %x, 2275 %chk2 = icmp ult i32 %x.inc2, %length276 call void(i1, ...) @llvm.experimental.guard(i1 %chk2) [ "deopt"() ]277 278 %x.inc3 = add i32 %x, 3279 %chk3 = icmp ult i32 %x.inc3, %length280 call void(i1, ...) @llvm.experimental.guard(i1 %chk3) [ "deopt"() ]281 ret void282}283 284 285define void @f_7(i32 %x, ptr %length_buf) {286; CHECK-LABEL: @f_7(287; CHECK-NEXT: entry:288; CHECK-NEXT: [[X_GW_FR:%.*]] = freeze i32 [[X:%.*]]289; CHECK-NEXT: [[LENGTH_A:%.*]] = load volatile i32, ptr [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]], !noundef !1290; CHECK-NEXT: [[LENGTH_B:%.*]] = load volatile i32, ptr [[LENGTH_BUF]], align 4, !range [[RNG0]], !noundef !1291; CHECK-NEXT: [[CHK0_A:%.*]] = icmp ult i32 [[X_GW_FR]], [[LENGTH_A]]292; CHECK-NEXT: [[CHK0_B:%.*]] = icmp ult i32 [[X_GW_FR]], [[LENGTH_B]]293; CHECK-NEXT: [[CHK0:%.*]] = and i1 [[CHK0_A]], [[CHK0_B]]294; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X_GW_FR]], 1295; CHECK-NEXT: [[CHK1_B:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH_B]]296; CHECK-NEXT: [[CHK1_A:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH_A]]297; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[CHK1_B]], [[CHK1_A]]298; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[TMP0]]299; CHECK-NEXT: [[X_INC2:%.*]] = add i32 [[X_GW_FR]], 2300; CHECK-NEXT: [[CHK2_A:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH_A]]301; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[CHK2_A]], [[CHK0_A]]302; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[CHK0_B]], [[TMP1]]303; CHECK-NEXT: [[CHK2_B:%.*]] = icmp ult i32 [[X_INC2]], [[LENGTH_B]]304; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[CHK2_B]], [[TMP2]]305; CHECK-NEXT: [[X_INC3:%.*]] = add i32 [[X_GW_FR]], 3306; CHECK-NEXT: [[CHK3_A:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH_A]]307; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[CHK3_A]], [[CHK0_A]]308; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[CHK0_B]], [[TMP3]]309; CHECK-NEXT: [[CHK3_B:%.*]] = icmp ult i32 [[X_INC3]], [[LENGTH_B]]310; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[CHK3_B]], [[TMP4]]311; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]312; CHECK-NEXT: [[CHK1:%.*]] = and i1 [[CHK1_A]], [[CHK1_B]]313; CHECK-NEXT: [[CHK2:%.*]] = and i1 [[CHK2_A]], [[CHK2_B]]314; CHECK-NEXT: [[CHK3:%.*]] = and i1 [[CHK3_A]], [[CHK3_B]]315; CHECK-NEXT: ret void316;317 318 319entry:320 %length_a = load volatile i32, ptr %length_buf, !range !0, !noundef !{}321 %length_b = load volatile i32, ptr %length_buf, !range !0, !noundef !{}322 %chk0.a = icmp ult i32 %x, %length_a323 %chk0.b = icmp ult i32 %x, %length_b324 %chk0 = and i1 %chk0.a, %chk0.b325 call void(i1, ...) @llvm.experimental.guard(i1 %chk0) [ "deopt"() ]326 327 %x.inc1 = add i32 %x, 1328 %chk1.a = icmp ult i32 %x.inc1, %length_a329 %chk1.b = icmp ult i32 %x.inc1, %length_b330 %chk1 = and i1 %chk1.a, %chk1.b331 call void(i1, ...) @llvm.experimental.guard(i1 %chk1) [ "deopt"() ]332 333 %x.inc2 = add i32 %x, 2334 %chk2.a = icmp ult i32 %x.inc2, %length_a335 %chk2.b = icmp ult i32 %x.inc2, %length_b336 %chk2 = and i1 %chk2.a, %chk2.b337 call void(i1, ...) @llvm.experimental.guard(i1 %chk2) [ "deopt"() ]338 339 %x.inc3 = add i32 %x, 3340 %chk3.a = icmp ult i32 %x.inc3, %length_a341 %chk3.b = icmp ult i32 %x.inc3, %length_b342 %chk3 = and i1 %chk3.a, %chk3.b343 call void(i1, ...) @llvm.experimental.guard(i1 %chk3) [ "deopt"() ]344 ret void345}346 347define void @f_8(i32 %x, ptr %length_buf) {348; Check that we clean nuw nsw flags349; CHECK-LABEL: @f_8(350; CHECK-NEXT: entry:351; CHECK-NEXT: [[X_GW_FR:%.*]] = freeze i32 [[X:%.*]]352; CHECK-NEXT: [[LENGTH:%.*]] = load i32, ptr [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]], !noundef !1353; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X_GW_FR]], [[LENGTH]]354; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X_GW_FR]], 1355; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]356; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]357; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]358; CHECK-NEXT: ret void359;360entry:361 %length = load i32, ptr %length_buf, !range !0, !noundef !{}362 %chk0 = icmp ult i32 %x, %length363 call void(i1, ...) @llvm.experimental.guard(i1 %chk0) [ "deopt"() ]364 365 %x.inc1 = add nuw nsw i32 %x, 1366 %chk1 = icmp ult i32 %x.inc1, %length367 call void(i1, ...) @llvm.experimental.guard(i1 %chk1) [ "deopt"() ]368 ret void369}370 371 372 373!0 = !{i32 0, i32 2147483648}374