704 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s3 4define i1 @test_second_and_condition_implied_by_first(i8 %x) {5; CHECK-LABEL: @test_second_and_condition_implied_by_first(6; CHECK-NEXT: entry:7; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 108; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[X]], 59; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]10; CHECK: then:11; CHECK-NEXT: ret i1 false12; CHECK: else:13; CHECK-NEXT: ret i1 true14;15entry:16 %c.1 = icmp ugt i8 %x, 1017 %t.1 = icmp ugt i8 %x, 518 %and = and i1 %c.1, %t.119 br i1 %and, label %then, label %else20 21then:22 ret i1 023 24else:25 ret i1 126}27 28define i1 @test_first_and_condition_implied_by_second_ops(i8 %x) {29; CHECK-LABEL: @test_first_and_condition_implied_by_second_ops(30; CHECK-NEXT: entry:31; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 1032; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[X]], 533; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]34; CHECK: then:35; CHECK-NEXT: ret i1 false36; CHECK: else:37; CHECK-NEXT: ret i1 true38;39entry:40 %c.1 = icmp ugt i8 %x, 1041 %t.1 = icmp ugt i8 %x, 542 %and = and i1 %t.1, %c.143 br i1 %and, label %then, label %else44 45then:46 ret i1 047 48else:49 ret i1 150}51 52define i1 @test_second_and_condition_implied_by_first_select_form(i8 %x) {53; CHECK-LABEL: @test_second_and_condition_implied_by_first_select_form(54; CHECK-NEXT: entry:55; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 1056; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[X]], 557; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]58; CHECK: then:59; CHECK-NEXT: ret i1 false60; CHECK: else:61; CHECK-NEXT: ret i1 true62;63entry:64 %c.1 = icmp ugt i8 %x, 1065 %t.1 = icmp ugt i8 %x, 566 %and = select i1 %c.1, i1 %t.1, i1 false67 br i1 %and, label %then, label %else68 69then:70 ret i1 071 72else:73 ret i1 174}75 76define i1 @test_first_and_condition_implied_by_second_select_form(i8 %x) {77; CHECK-LABEL: @test_first_and_condition_implied_by_second_select_form(78; CHECK-NEXT: entry:79; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 1080; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[X]], 581; CHECK-NEXT: [[AND:%.*]] = select i1 [[T_1]], i1 [[C_1]], i1 false82; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]83; CHECK: then:84; CHECK-NEXT: ret i1 false85; CHECK: else:86; CHECK-NEXT: ret i1 true87;88entry:89 %c.1 = icmp ugt i8 %x, 1090 %t.1 = icmp ugt i8 %x, 591 %and = select i1 %t.1, i1 %c.1, i1 false92 br i1 %and, label %then, label %else93 94then:95 ret i1 096 97else:98 ret i1 199}100 101define i1 @test_same_cond_for_and(i8 %x) {102; CHECK-LABEL: @test_same_cond_for_and(103; CHECK-NEXT: entry:104; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10105; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]106; CHECK: then:107; CHECK-NEXT: ret i1 false108; CHECK: else:109; CHECK-NEXT: ret i1 true110;111entry:112 %c.1 = icmp ugt i8 %x, 10113 %and = and i1 %c.1, %c.1114 br i1 %and, label %then, label %else115 116then:117 ret i1 0118 119else:120 ret i1 1121}122 123define i1 @test_same_cond_for_and_select_form(i8 %x) {124; CHECK-LABEL: @test_same_cond_for_and_select_form(125; CHECK-NEXT: entry:126; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10127; CHECK-NEXT: [[AND:%.*]] = select i1 [[C_1]], i1 [[C_1]], i1 false128; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]129; CHECK: then:130; CHECK-NEXT: ret i1 false131; CHECK: else:132; CHECK-NEXT: ret i1 true133;134entry:135 %c.1 = icmp ugt i8 %x, 10136 %and = select i1 %c.1, i1 %c.1, i1 false137 br i1 %and, label %then, label %else138 139then:140 ret i1 0141 142else:143 ret i1 1144}145 146define i1 @test_second_and_condition_not_implied_by_first(i8 %x) {147; CHECK-LABEL: @test_second_and_condition_not_implied_by_first(148; CHECK-NEXT: entry:149; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10150; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i8 [[X]], 5151; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]152; CHECK: then:153; CHECK-NEXT: ret i1 false154; CHECK: else:155; CHECK-NEXT: ret i1 true156;157entry:158 %c.1 = icmp ugt i8 %x, 10159 %c.2 = icmp ugt i8 %x, 5160 %and = and i1 %c.2, %c.1161 br i1 %and, label %then, label %else162 163then:164 ret i1 0165 166else:167 ret i1 1168}169 170define i1 @test_remove_variables(i1 %c, ptr %A, i64 %B, ptr %C) {171; CHECK-LABEL: @test_remove_variables(172; CHECK-NEXT: entry:173; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN_1:%.*]], label [[EXIT:%.*]]174; CHECK: then.1:175; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C:%.*]], align 8176; CHECK-NEXT: [[C_1:%.*]] = icmp ult ptr [[TMP0]], [[A:%.*]]177; CHECK-NEXT: br i1 [[C_1]], label [[THEN_2:%.*]], label [[ELSE_2:%.*]]178; CHECK: then.2:179; CHECK-NEXT: [[C_3:%.*]] = icmp sgt i64 [[B:%.*]], 0180; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[C_3]]181; CHECK-NEXT: ret i1 [[AND]]182; CHECK: else.2:183; CHECK-NEXT: ret i1 false184; CHECK: exit:185; CHECK-NEXT: ret i1 true186;187entry:188 br i1 %c, label %then.1, label %exit189 190then.1:191 %0 = load ptr, ptr %C, align 8192 %c.1 = icmp ult ptr %0, %A193 br i1 %c.1, label %then.2, label %else.2194 195then.2:196 %c.2 = icmp ne ptr %A, null197 %c.3 = icmp sgt i64 %B, 0198 %and = and i1 %c.2, %c.3199 ret i1 %and200 201else.2:202 ret i1 0203 204exit:205 %t = icmp eq ptr null, null206 ret i1 %t207}208 209define i1 @test_and_op_0_simplified(i32 %v) {210; CHECK-LABEL: @test_and_op_0_simplified(211; CHECK-NEXT: entry:212; CHECK-NEXT: [[C_1:%.*]] = icmp sgt i32 [[V:%.*]], 0213; CHECK-NEXT: [[AND:%.*]] = and i1 false, [[C_1]]214; CHECK-NEXT: ret i1 [[AND]]215;216entry:217 %c.1 = icmp sgt i32 %v, 0218 %t.1 = icmp sgt i32 0, 0219 %and = and i1 %t.1, %c.1220 ret i1 %and221}222 223define i1 @test_and_op_1_simplified(i32 %v) {224; CHECK-LABEL: @test_and_op_1_simplified(225; CHECK-NEXT: entry:226; CHECK-NEXT: [[C_1:%.*]] = icmp sgt i32 [[V:%.*]], 0227; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_1]], false228; CHECK-NEXT: ret i1 [[AND]]229;230entry:231 %c.1 = icmp sgt i32 %v, 0232 %t.1 = icmp sgt i32 0, 0233 %and = and i1 %c.1, %t.1234 ret i1 %and235}236 237define i1 @and_select_not_used_for_branch(i32 %x, i32 %y,i32 %z) {238; CHECK-LABEL: @and_select_not_used_for_branch(239; CHECK-NEXT: entry:240; CHECK-NEXT: [[C_1:%.*]] = icmp ne i32 [[X:%.*]], 0241; CHECK-NEXT: [[C_2:%.*]] = icmp ne i32 [[Y:%.*]], 0242; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[X]], 16243; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]]244; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[EXIT:%.*]]245; CHECK: then:246; CHECK-NEXT: [[C_4:%.*]] = icmp eq i32 [[Z:%.*]], 0247; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C_4]], i1 true, i1 false248; CHECK-NEXT: br label [[EXIT]]249; CHECK: exit:250; CHECK-NEXT: [[RES:%.*]] = phi i1 [ [[C_1]], [[ENTRY:%.*]] ], [ [[SEL]], [[THEN]] ]251; CHECK-NEXT: ret i1 [[RES]]252;253entry:254 %c.1 = icmp ne i32 %x, 0255 %c.2 = icmp ne i32 %y, 0256 %c.3 = icmp eq i32 %x, 16257 %and = and i1 %c.2, %c.3258 br i1 %and, label %then, label %exit259 260then:261 %c.4 = icmp eq i32 %z, 0262 %sel = select i1 %c.4, i1 %c.1, i1 false263 br label %exit264 265exit:266 %res = phi i1 [ %c.1, %entry ], [ %sel, %then ]267 ret i1 %res268}269 270define i1 @and_select_scope_limited(i32 %x, i32 %y, i32 %z) {271; CHECK-LABEL: @and_select_scope_limited(272; CHECK-NEXT: entry:273; CHECK-NEXT: [[C_1:%.*]] = icmp ne i32 [[X:%.*]], 0274; CHECK-NEXT: [[C_2:%.*]] = icmp ne i32 [[Y:%.*]], 0275; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[X]], 16276; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]]277; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[EXIT:%.*]]278; CHECK: then:279; CHECK-NEXT: [[C_4:%.*]] = icmp eq i32 [[Z:%.*]], 0280; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C_4]], i1 true, i1 false281; CHECK-NEXT: br i1 [[SEL]], label [[T_1:%.*]], label [[EXIT]]282; CHECK: t.1:283; CHECK-NEXT: ret i1 true284; CHECK: exit:285; CHECK-NEXT: [[RES:%.*]] = phi i1 [ [[C_1]], [[ENTRY:%.*]] ], [ [[SEL]], [[THEN]] ]286; CHECK-NEXT: ret i1 [[RES]]287;288entry:289 %c.1 = icmp ne i32 %x, 0290 %c.2 = icmp ne i32 %y, 0291 %c.3 = icmp eq i32 %x, 16292 %and = and i1 %c.2, %c.3293 br i1 %and, label %then, label %exit294 295then:296 %c.4 = icmp eq i32 %z, 0297 %sel = select i1 %c.4, i1 %c.1, i1 false298 br i1 %sel, label %t.1, label %exit299 300t.1:301 ret i1 %c.1302 303exit:304 %res = phi i1 [ %c.1, %entry ], [ %sel, %then ]305 ret i1 %res306}307 308declare void @use(ptr)309 310define void @test_monotonic_ptr_iv_inc_1_eq_to_uge(ptr %start, i16 %len) {311; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge(312; CHECK-NEXT: entry:313; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]314; CHECK-NEXT: br label [[LOOP_PH:%.*]]315; CHECK: loop.ph:316; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]317; CHECK: loop.header:318; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]319; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp sgt i16 [[LEN]], 0320; CHECK-NEXT: [[C:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]]321; CHECK-NEXT: [[AND_0:%.*]] = and i1 [[LEN_NEG]], [[C]]322; CHECK-NEXT: br i1 [[AND_0]], label [[FOR_BODY:%.*]], label [[EXIT:%.*]]323; CHECK: for.body:324; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]]325; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]326; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]]327; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]328; CHECK: loop.latch:329; CHECK-NEXT: call void @use(ptr [[PTR_IV]])330; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1331; CHECK-NEXT: br label [[LOOP_HEADER]]332; CHECK: exit:333; CHECK-NEXT: ret void334;335entry:336 %upper = getelementptr inbounds i32, ptr %start, i16 %len337 br label %loop.ph338 339loop.ph:340 br label %loop.header341 342loop.header:343 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]344 %len.neg = icmp sgt i16 %len, 0345 %c = icmp ne ptr %ptr.iv, %upper346 %and.0 = and i1 %len.neg, %c347 br i1 %and.0, label %for.body, label %exit348 349for.body:350 %t.1 = icmp uge ptr %ptr.iv, %start351 %t.2 = icmp ult ptr %ptr.iv, %upper352 %and = and i1 %t.1, %t.2353 br i1 %and, label %loop.latch, label %exit354 355loop.latch:356 call void @use(ptr %ptr.iv)357 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1358 br label %loop.header359 360exit:361 ret void362}363 364define i1 @test_and_used_in_false_branch(i8 %x) {365; CHECK-LABEL: @test_and_used_in_false_branch(366; CHECK-NEXT: entry:367; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10368; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[X]], 5369; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]370; CHECK: then:371; CHECK-NEXT: ret i1 true372; CHECK: else:373; CHECK-NEXT: ret i1 [[T_1]]374;375 376entry:377 %c.1 = icmp ugt i8 %x, 10378 %t.1 = icmp ugt i8 %x, 5379 %and = and i1 %c.1, %t.1380 br i1 %and, label %then, label %else381 382then:383 ret i1 %t.1384 385else:386 ret i1 %t.1387}388 389define i1 @test_or_used_in_false_branch(i8 %x) {390; CHECK-LABEL: @test_or_used_in_false_branch(391; CHECK-NEXT: entry:392; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10393; CHECK-NEXT: [[T_1:%.*]] = icmp ule i8 [[X]], 5394; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]395; CHECK: then:396; CHECK-NEXT: ret i1 [[T_1]]397; CHECK: else:398; CHECK-NEXT: ret i1 false399;400 401entry:402 %c.1 = icmp ule i8 %x, 10403 %t.1 = icmp ule i8 %x, 5404 %and = or i1 %c.1, %t.1405 br i1 %and, label %then, label %else406 407then:408 ret i1 %t.1409 410else:411 ret i1 %t.1412}413 414define i1 @test_or_used_in_false_branch2(i8 %x) {415; CHECK-LABEL: @test_or_used_in_false_branch2(416; CHECK-NEXT: entry:417; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10418; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[X]], 5419; CHECK-NEXT: br i1 [[T_1]], label [[THEN:%.*]], label [[ELSE:%.*]]420; CHECK: then:421; CHECK-NEXT: ret i1 [[T_1]]422; CHECK: else:423; CHECK-NEXT: ret i1 false424;425 426entry:427 %c.1 = icmp ugt i8 %x, 10428 %t.1 = icmp ugt i8 %x, 5429 %and = or i1 %c.1, %t.1430 br i1 %and, label %then, label %else431 432then:433 ret i1 %t.1434 435else:436 ret i1 %t.1437}438 439define i1 @and_select_first_implies_second_may_be_poison(ptr noundef %A, ptr noundef %B) {440; CHECK-LABEL: @and_select_first_implies_second_may_be_poison(441; CHECK-NEXT: entry:442; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]]443; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1444; CHECK-NEXT: [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]]445; CHECK-NEXT: ret i1 [[C_2]]446;447entry:448 %c.1 = icmp ne ptr %A, %B449 %gep = getelementptr inbounds ptr, ptr %B, i64 -1450 %c.2 = icmp ugt ptr %gep, %A451 %and = select i1 %c.2, i1 %c.1, i1 false452 ret i1 %and453}454 455define i1 @and_select_second_implies_first_may_be_poison(ptr noundef %A, ptr noundef %B) {456; CHECK-LABEL: @and_select_second_implies_first_may_be_poison(457; CHECK-NEXT: entry:458; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]]459; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1460; CHECK-NEXT: [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]]461; CHECK-NEXT: [[AND:%.*]] = select i1 [[C_1]], i1 [[C_2]], i1 false462; CHECK-NEXT: ret i1 [[AND]]463;464entry:465 %c.1 = icmp ne ptr %A, %B466 %gep = getelementptr inbounds ptr, ptr %B, i64 -1467 %c.2 = icmp ugt ptr %gep, %A468 %and = select i1 %c.1, i1 %c.2, i1 false469 ret i1 %and470}471 472define i1 @and_select_second_implies_first_guaranteed_not_poison(ptr noundef %A, ptr noundef %B) {473; CHECK-LABEL: @and_select_second_implies_first_guaranteed_not_poison(474; CHECK-NEXT: entry:475; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]]476; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1477; CHECK-NEXT: [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]]478; CHECK-NEXT: call void @no_noundef(i1 [[C_2]])479; CHECK-NEXT: [[AND:%.*]] = select i1 [[C_1]], i1 [[C_2]], i1 false480; CHECK-NEXT: ret i1 [[AND]]481;482entry:483 %c.1 = icmp ne ptr %A, %B484 %gep = getelementptr inbounds ptr, ptr %B, i64 -1485 %c.2 = icmp ugt ptr %gep, %A486 call void @no_noundef(i1 %c.2)487 %and = select i1 %c.1, i1 %c.2, i1 false488 ret i1 %and489}490 491define void @and_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {492; CHECK-LABEL: @and_tree_second_implies_first(493; CHECK-NEXT: entry:494; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]495; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]496; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP0]], [[CMP1]]497; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]498; CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[RETURN:%.*]]499; CHECK: if.then:500; CHECK-NEXT: call void @side_effect()501; CHECK-NEXT: br label [[RETURN]]502; CHECK: return:503; CHECK-NEXT: ret void504;505entry:506 %cmp0 = icmp sge i32 %v0, %v1507 %cmp1 = icmp sge i32 %v1, %v2508 %and1 = and i1 %cmp0, %cmp1509 %cmp2 = icmp slt i32 %v0, %v2510 %and2 = and i1 %cmp2, %and1511 br i1 %and2, label %if.then, label %return512 513if.then:514 call void @side_effect()515 br label %return516 517return:518 ret void519}520 521define void @and_tree_second_implies_first_perm1(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {522; CHECK-LABEL: @and_tree_second_implies_first_perm1(523; CHECK-NEXT: entry:524; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]525; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]526; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]527; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP2]], [[CMP1]]528; CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[RETURN:%.*]]529; CHECK: if.then:530; CHECK-NEXT: call void @side_effect()531; CHECK-NEXT: br label [[RETURN]]532; CHECK: return:533; CHECK-NEXT: ret void534;535entry:536 %cmp0 = icmp sge i32 %v0, %v1537 %cmp1 = icmp sge i32 %v1, %v2538 %cmp2 = icmp slt i32 %v0, %v2539 %and1 = and i1 %cmp2, %cmp1540 %and2 = and i1 %cmp0, %and1541 br i1 %and2, label %if.then, label %return542 543if.then:544 call void @side_effect()545 br label %return546 547return:548 ret void549}550 551 552define void @and_tree_second_implies_first_perm2(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {553; CHECK-LABEL: @and_tree_second_implies_first_perm2(554; CHECK-NEXT: entry:555; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]556; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]557; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]558; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP0]], [[CMP2]]559; CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[RETURN:%.*]]560; CHECK: if.then:561; CHECK-NEXT: call void @side_effect()562; CHECK-NEXT: br label [[RETURN]]563; CHECK: return:564; CHECK-NEXT: ret void565;566entry:567 %cmp0 = icmp sge i32 %v0, %v1568 %cmp1 = icmp sge i32 %v1, %v2569 %cmp2 = icmp slt i32 %v0, %v2570 %and1 = and i1 %cmp0, %cmp2571 %and2 = and i1 %cmp1, %and1572 br i1 %and2, label %if.then, label %return573 574if.then:575 call void @side_effect()576 br label %return577 578return:579 ret void580}581 582define void @logical_and_tree_second_implies_first(i32 %v0, i32 %v1, i32 %v2) {583; CHECK-LABEL: @logical_and_tree_second_implies_first(584; CHECK-NEXT: entry:585; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]586; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]587; CHECK-NEXT: [[AND1:%.*]] = select i1 [[CMP0]], i1 [[CMP1]], i1 false588; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]589; CHECK-NEXT: [[AND2:%.*]] = select i1 [[CMP2]], i1 [[AND1]], i1 false590; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]591; CHECK: if.then:592; CHECK-NEXT: call void @side_effect()593; CHECK-NEXT: br label [[RETURN]]594; CHECK: return:595; CHECK-NEXT: ret void596;597entry:598 %cmp0 = icmp sge i32 %v0, %v1599 %cmp1 = icmp sge i32 %v1, %v2600 %and1 = select i1 %cmp0, i1 %cmp1, i1 false601 %cmp2 = icmp slt i32 %v0, %v2602 %and2 = select i1 %cmp2, i1 %and1, i1 false603 br i1 %and2, label %if.then, label %return604 605if.then:606 call void @side_effect()607 br label %return608 609return:610 ret void611}612 613define void @or_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {614; CHECK-LABEL: @or_tree_second_implies_first(615; CHECK-NEXT: entry:616; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]617; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]618; CHECK-NEXT: [[AND1:%.*]] = or i1 [[CMP0]], [[CMP1]]619; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]620; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[RETURN:%.*]]621; CHECK: if.then:622; CHECK-NEXT: call void @side_effect()623; CHECK-NEXT: br label [[RETURN]]624; CHECK: return:625; CHECK-NEXT: ret void626;627entry:628 %cmp0 = icmp sge i32 %v0, %v1629 %cmp1 = icmp sge i32 %v1, %v2630 %and1 = or i1 %cmp0, %cmp1631 %cmp2 = icmp slt i32 %v0, %v2632 %and2 = or i1 %cmp2, %and1633 br i1 %and2, label %if.then, label %return634 635if.then:636 call void @side_effect()637 br label %return638 639return:640 ret void641}642 643define void @or_tree_second_implies_first_with_unknown_cond(i64 %x, i1 %cond) {644; CHECK-LABEL: @or_tree_second_implies_first_with_unknown_cond(645; CHECK-NEXT: entry:646; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X:%.*]], 1647; CHECK-NEXT: [[OR1:%.*]] = select i1 [[CMP1]], i1 [[COND:%.*]], i1 false648; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[X]], 2649; CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END:%.*]]650; CHECK: if.then:651; CHECK-NEXT: call void @side_effect()652; CHECK-NEXT: br label [[IF_END]]653; CHECK: if.end:654; CHECK-NEXT: ret void655;656entry:657 %cmp1 = icmp ugt i64 %x, 1658 %or1 = select i1 %cmp1, i1 %cond, i1 false659 %cmp2 = icmp ult i64 %x, 2660 %or2 = select i1 %or1, i1 %cmp2, i1 false661 br i1 %or2, label %if.then, label %if.end662 663if.then:664 call void @side_effect()665 br label %if.end666 667if.end:668 ret void669}670 671define void @negative_and_or_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) {672; CHECK-LABEL: @negative_and_or_tree_second_implies_first(673; CHECK-NEXT: entry:674; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]]675; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]]676; CHECK-NEXT: [[AND1:%.*]] = or i1 [[CMP0]], [[CMP1]]677; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]]678; CHECK-NEXT: [[AND2:%.*]] = and i1 [[CMP2]], [[AND1]]679; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]680; CHECK: if.then:681; CHECK-NEXT: call void @side_effect()682; CHECK-NEXT: br label [[RETURN]]683; CHECK: return:684; CHECK-NEXT: ret void685;686entry:687 %cmp0 = icmp sge i32 %v0, %v1688 %cmp1 = icmp sge i32 %v1, %v2689 %and1 = or i1 %cmp0, %cmp1690 %cmp2 = icmp slt i32 %v0, %v2691 %and2 = and i1 %cmp2, %and1692 br i1 %and2, label %if.then, label %return693 694if.then:695 call void @side_effect()696 br label %return697 698return:699 ret void700}701 702declare void @side_effect()703declare void @no_noundef(i1 noundef)704