1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3 4declare i1 @cond() 5declare void @clobber() 6 7 8define void @test_unreachable_latch(ptr %start, ptr %b) { 9; CHECK-LABEL: define void @test_unreachable_latch 10; CHECK-SAME: (ptr [[START:%.*]], ptr [[B:%.*]]) { 11; CHECK-NEXT: entry: 12; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 13; CHECK: loop.header: 14; CHECK-NEXT: [[NODE_1:%.*]] = phi ptr [ [[START]], [[ENTRY:%.*]] ], [ null, [[LOOP_LATCH:%.*]] ] 15; CHECK-NEXT: [[C_0:%.*]] = icmp ne ptr [[NODE_1]], null 16; CHECK-NEXT: br i1 [[C_0]], label [[THEN:%.*]], label [[EXIT:%.*]] 17; CHECK: loop.latch: 18; CHECK-NEXT: call void @clobber() 19; CHECK-NEXT: br label [[LOOP_HEADER]] 20; CHECK: if: 21; CHECK-NEXT: [[C_2:%.*]] = icmp ne ptr [[B]], null 22; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_0]] 23; CHECK-NEXT: br i1 [[AND]], label [[THEN]], label [[EXIT]] 24; CHECK: then: 25; CHECK-NEXT: call void @clobber() 26; CHECK-NEXT: br label [[EXIT]] 27; CHECK: exit: 28; CHECK-NEXT: ret void 29; 30entry: 31 br label %loop.header 32 33loop.header: 34 %node.1 = phi ptr [ %start, %entry ], [ null, %loop.latch ] 35 %c.0 = icmp ne ptr %node.1, null 36 br i1 %c.0, label %then, label %exit 37 38loop.latch: ; No predecessors! 39 call void @clobber() 40 br label %loop.header 41 42if: 43 %c.2 = icmp ne ptr %b, null 44 %and = and i1 %c.2, %c.0 45 br i1 %and, label %then, label %exit 46 47then: 48 call void @clobber() 49 br label %exit 50 51exit: 52 ret void 53} 54 55define void @test_cond_multi_use_with_one_use_simplified_before_adding_ne_fact(ptr %start, ptr %b) { 56; CHECK-LABEL: define void @test_cond_multi_use_with_one_use_simplified_before_adding_ne_fact 57; CHECK-SAME: (ptr [[START:%.*]], ptr [[B:%.*]]) { 58; CHECK-NEXT: entry: 59; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 60; CHECK: loop.header: 61; CHECK-NEXT: [[NODE_1:%.*]] = phi ptr [ [[START]], [[ENTRY:%.*]] ], [ null, [[LOOP_LATCH:%.*]] ] 62; CHECK-NEXT: [[C_0:%.*]] = icmp ne ptr [[NODE_1]], null 63; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]] 64; CHECK: loop.latch: 65; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 66; CHECK-NEXT: br i1 [[C_1]], label [[IF:%.*]], label [[LOOP_HEADER]] 67; CHECK: if: 68; CHECK-NEXT: [[C_2:%.*]] = icmp ne ptr [[B]], null 69; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], true 70; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[EXIT]] 71; CHECK: then: 72; CHECK-NEXT: call void @clobber() 73; CHECK-NEXT: br label [[EXIT]] 74; CHECK: exit: 75; CHECK-NEXT: ret void 76; 77entry: 78 br label %loop.header 79 80loop.header: 81 %node.1 = phi ptr [ %start, %entry ], [ null, %loop.latch ] 82 %c.0 = icmp ne ptr %node.1, null 83 br i1 %c.0, label %loop.latch, label %exit 84 85loop.latch: 86 %c.1 = call i1 @cond() 87 br i1 %c.1, label %if, label %loop.header 88 89if: 90 %c.2 = icmp ne ptr %b, null 91 %and = and i1 %c.2, %c.0 92 br i1 %and, label %then, label %exit 93 94then: 95 call void @clobber() 96 br label %exit 97 98exit: 99 ret void 100} 101