1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3 4declare void @use(i1) 5declare void @llvm.assume(i1) 6 7define void @phi_loop_1(i8 %x) { 8; CHECK-LABEL: @phi_loop_1( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: [[C_0:%.*]] = icmp uge i8 [[X:%.*]], 10 11; CHECK-NEXT: br i1 [[C_0]], label [[LOOP:%.*]], label [[EXIT:%.*]] 12; CHECK: loop: 13; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 14; CHECK-NEXT: [[C_PHI:%.*]] = phi i1 [ false, [[ENTRY]] ], [ true, [[LOOP]] ] 15; CHECK-NEXT: call void @use(i1 true) 16; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 17; CHECK-NEXT: [[EC:%.*]] = icmp ult i8 [[IV_NEXT]], 3 18; CHECK-NEXT: br i1 [[EC]], label [[LOOP]], label [[LOOP_EXIT:%.*]] 19; CHECK: loop.exit: 20; CHECK-NEXT: call void @use(i1 [[C_PHI]]) 21; CHECK-NEXT: br label [[EXIT]] 22; CHECK: exit: 23; CHECK-NEXT: ret void 24; 25entry: 26 %c.0 = icmp uge i8 %x, 10 27 br i1 %c.0, label %loop, label %exit 28 29loop: 30 %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ] 31 %c.phi = phi i1 [ false, %entry ], [ %t.1, %loop ] 32 %t.1 = icmp uge i8 %x, 8 33 call void @use(i1 %t.1) 34 %iv.next = add i8 %iv, 1 35 %ec = icmp ult i8 %iv.next, 3 36 br i1 %ec, label %loop, label %loop.exit 37 38loop.exit: 39 call void @use(i1 %c.phi) 40 br label %exit 41 42exit: 43 ret void 44} 45 46define void @phi_loop_2(i8 %x) { 47; CHECK-LABEL: @phi_loop_2( 48; CHECK-NEXT: entry: 49; CHECK-NEXT: [[C_0:%.*]] = icmp uge i8 [[X:%.*]], 10 50; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_1_HEADER:%.*]], label [[EXIT:%.*]] 51; CHECK: loop.1.header: 52; CHECK-NEXT: [[C_PHI:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ true, [[LOOP_1_LATCH:%.*]] ] 53; CHECK-NEXT: br label [[LOOP_2:%.*]] 54; CHECK: loop.2: 55; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 0, [[LOOP_1_HEADER]] ], [ [[IV_NEXT:%.*]], [[LOOP_2]] ] 56; CHECK-NEXT: call void @use(i1 true) 57; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 58; CHECK-NEXT: [[EC:%.*]] = icmp ult i8 [[IV_NEXT]], 3 59; CHECK-NEXT: br i1 [[EC]], label [[LOOP_2]], label [[LOOP_1_LATCH]] 60; CHECK: loop.1.latch: 61; CHECK-NEXT: br i1 false, label [[LOOP_1_HEADER]], label [[LOOP_1_EXIT:%.*]] 62; CHECK: loop.1.exit: 63; CHECK-NEXT: call void @use(i1 [[C_PHI]]) 64; CHECK-NEXT: br label [[EXIT]] 65; CHECK: exit: 66; CHECK-NEXT: ret void 67; 68entry: 69 %c.0 = icmp uge i8 %x, 10 70 br i1 %c.0, label %loop.1.header, label %exit 71 72loop.1.header: 73 %c.phi = phi i1 [ false, %entry ], [ %t.1, %loop.1.latch ] 74 br label %loop.2 75 76loop.2: 77 %iv = phi i8 [ 0, %loop.1.header ], [ %iv.next, %loop.2 ] 78 %t.1 = icmp uge i8 %x, 8 79 call void @use(i1 %t.1) 80 %iv.next = add i8 %iv, 1 81 %ec = icmp ult i8 %iv.next, 3 82 br i1 %ec, label %loop.2, label %loop.1.latch 83 84loop.1.latch: 85 br i1 false, label %loop.1.header, label %loop.1.exit 86 87loop.1.exit: 88 call void @use(i1 %c.phi) 89 br label %exit 90 91exit: 92 ret void 93} 94 95define void @phi_loop_3(i8 %x, i1 %c) { 96; CHECK-LABEL: @phi_loop_3( 97; CHECK-NEXT: entry: 98; CHECK-NEXT: [[C_0:%.*]] = icmp uge i8 [[X:%.*]], 10 99; CHECK-NEXT: br i1 [[C_0]], label [[LOOP:%.*]], label [[EXIT:%.*]] 100; CHECK: loop: 101; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 102; CHECK-NEXT: [[C_PHI:%.*]] = phi i1 [ false, [[ENTRY]] ], [ true, [[LOOP_LATCH]] ] 103; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_LATCH]], label [[LOOP_EXIT:%.*]] 104; CHECK: loop.latch: 105; CHECK-NEXT: call void @use(i1 true) 106; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 107; CHECK-NEXT: [[EC:%.*]] = icmp ult i8 [[IV_NEXT]], 3 108; CHECK-NEXT: br i1 [[EC]], label [[LOOP]], label [[LOOP_EXIT]] 109; CHECK: loop.exit: 110; CHECK-NEXT: call void @use(i1 [[C_PHI]]) 111; CHECK-NEXT: br label [[EXIT]] 112; CHECK: exit: 113; CHECK-NEXT: ret void 114; 115entry: 116 %c.0 = icmp uge i8 %x, 10 117 br i1 %c.0, label %loop, label %exit 118 119loop: 120 %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop.latch ] 121 %c.phi = phi i1 [ false, %entry ], [ %t.1, %loop.latch ] 122 br i1 %c, label %loop.latch, label %loop.exit 123 124loop.latch: 125 %t.1 = icmp uge i8 %x, 8 126 call void @use(i1 %t.1) 127 %iv.next = add i8 %iv, 1 128 %ec = icmp ult i8 %iv.next, 3 129 br i1 %ec, label %loop, label %loop.exit 130 131loop.exit: 132 call void @use(i1 %c.phi) 133 br label %exit 134 135exit: 136 ret void 137} 138 139define i1 @test_if_then_1(i8 %x) { 140; CHECK-LABEL: @test_if_then_1( 141; CHECK-NEXT: entry: 142; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i8 [[X:%.*]], 1 143; CHECK-NEXT: br i1 [[CMP1]], label [[IF:%.*]], label [[JOIN:%.*]] 144; CHECK: if: 145; CHECK-NEXT: br label [[JOIN]] 146; CHECK: join: 147; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ true, [[IF]] ], [ false, [[ENTRY:%.*]] ] 148; CHECK-NEXT: ret i1 [[PHI]] 149; 150entry: 151 %cmp1 = icmp sgt i8 %x, 1 152 br i1 %cmp1, label %if, label %join 153 154if: 155 %cmp2 = icmp sgt i8 %x, 0 156 br label %join 157 158join: 159 %phi = phi i1 [ %cmp2, %if ], [ false, %entry ] 160 ret i1 %phi 161} 162 163 164define i1 @test_if_then_2(i1 %c, i8 %x) { 165; CHECK-LABEL: @test_if_then_2( 166; CHECK-NEXT: entry: 167; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[JOIN:%.*]] 168; CHECK: if: 169; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i8 [[X:%.*]], 1 170; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]]) 171; CHECK-NEXT: br label [[JOIN]] 172; CHECK: join: 173; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ true, [[IF]] ], [ false, [[ENTRY:%.*]] ] 174; CHECK-NEXT: ret i1 [[PHI]] 175; 176entry: 177 %cmp2 = icmp sgt i8 %x, 0 178 br i1 %c, label %if, label %join 179 180if: 181 %cmp1 = icmp sgt i8 %x, 1 182 call void @llvm.assume(i1 %cmp1) 183 br label %join 184 185join: 186 %phi = phi i1 [ %cmp2, %if ], [ false, %entry ] 187 ret i1 %phi 188} 189 190define i1 @test_if_then_3(i1 %c.0, i8 %x) { 191; CHECK-LABEL: @test_if_then_3( 192; CHECK-NEXT: entry: 193; CHECK-NEXT: br i1 [[C_0:%.*]], label [[IF:%.*]], label [[JOIN:%.*]] 194; CHECK: if: 195; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i8 [[X:%.*]], 1 196; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 [[X]], 1 197; CHECK-NEXT: br i1 [[CMP1]], label [[THEN_1:%.*]], label [[JOIN]] 198; CHECK: then.1: 199; CHECK-NEXT: br label [[JOIN]] 200; CHECK: join: 201; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ [[CMP2]], [[IF]] ], [ true, [[THEN_1]] ], [ false, [[ENTRY:%.*]] ] 202; CHECK-NEXT: ret i1 [[PHI]] 203; 204entry: 205 br i1 %c.0, label %if, label %join 206 207if: 208 %cmp1 = icmp sgt i8 %x, 1 209 %cmp2 = icmp sgt i8 %x, 1 210 br i1 %cmp1, label %then.1, label %join 211 212then.1: 213 br label %join 214 215join: 216 %phi = phi i1 [ %cmp2, %if ], [ %cmp2, %then.1 ], [ false, %entry ] 217 ret i1 %phi 218} 219 220define i1 @test_if_then_4(i1 %c.0, i8 %x) { 221; CHECK-LABEL: @test_if_then_4( 222; CHECK-NEXT: entry: 223; CHECK-NEXT: br i1 [[C_0:%.*]], label [[IF:%.*]], label [[JOIN:%.*]] 224; CHECK: if: 225; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i8 [[X:%.*]], 1 226; CHECK-NEXT: br i1 [[CMP1]], label [[THEN_1:%.*]], label [[ELSE_1:%.*]] 227; CHECK: then.1: 228; CHECK-NEXT: br label [[JOIN]] 229; CHECK: else.1: 230; CHECK-NEXT: br label [[JOIN]] 231; CHECK: join: 232; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ false, [[ELSE_1]] ], [ true, [[THEN_1]] ], [ false, [[ENTRY:%.*]] ] 233; CHECK-NEXT: ret i1 [[PHI]] 234; 235entry: 236 br i1 %c.0, label %if, label %join 237 238if: 239 %cmp1 = icmp sgt i8 %x, 1 240 %cmp2 = icmp sgt i8 %x, 1 241 br i1 %cmp1, label %then.1, label %else.1 242 243then.1: 244 br label %join 245 246else.1: 247 br label %join 248 249join: 250 %phi = phi i1 [ %cmp2, %else.1 ], [ %cmp2, %then.1 ], [ false, %entry ] 251 ret i1 %phi 252} 253