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) 5 6define void @iv_known_non_negative_iv_constant_trip_count_uge() { 7; CHECK-LABEL: @iv_known_non_negative_iv_constant_trip_count_uge( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 10; CHECK: loop.header: 11; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 12; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[IV]], 2 13; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]] 14; CHECK: loop.latch: 15; CHECK-NEXT: call void @use(i1 true) 16; CHECK-NEXT: call void @use(i1 true) 17; CHECK-NEXT: call void @use(i1 false) 18; CHECK-NEXT: call void @use(i1 false) 19; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 20; CHECK-NEXT: br label [[LOOP_HEADER]] 21; CHECK: exit.1: 22; CHECK-NEXT: ret void 23; 24entry: 25 br label %loop.header 26 27loop.header: 28 %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop.latch ] 29 %cmp = icmp uge i8 %iv, 2 30 br i1 %cmp, label %loop.latch, label %exit.1 31 32loop.latch: 33 %t.1 = icmp uge i8 %iv, 2 34 call void @use(i1 %t.1) 35 %t.2 = icmp sge i8 %iv, 2 36 call void @use(i1 %t.2) 37 %f.1 = icmp ult i8 %iv, 2 38 call void @use(i1 %f.1) 39 %f.2 = icmp slt i8 %iv, 2 40 call void @use(i1 %f.2) 41 %iv.next = add nsw nuw i8 %iv, 1 42 br label %loop.header 43 44exit.1: 45 ret void 46} 47 48define void @iv_known_non_negative_iv_variable_trip_count_uge(i8 %N) { 49; CHECK-LABEL: @iv_known_non_negative_iv_variable_trip_count_uge( 50; CHECK-NEXT: entry: 51; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 52; CHECK: loop.header: 53; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 54; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[IV]], [[N:%.*]] 55; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]] 56; CHECK: loop.latch: 57; CHECK-NEXT: call void @use(i1 true) 58; CHECK-NEXT: call void @use(i1 true) 59; CHECK-NEXT: call void @use(i1 false) 60; CHECK-NEXT: call void @use(i1 false) 61; CHECK-NEXT: [[C_0:%.*]] = icmp ugt i8 [[IV]], 2 62; CHECK-NEXT: call void @use(i1 [[C_0]]) 63; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 64; CHECK-NEXT: br label [[LOOP_HEADER]] 65; CHECK: exit.1: 66; CHECK-NEXT: ret void 67; 68entry: 69 br label %loop.header 70 71loop.header: 72 %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop.latch ] 73 %cmp = icmp uge i8 %iv, %N 74 br i1 %cmp, label %loop.latch, label %exit.1 75 76loop.latch: 77 %t.1 = icmp uge i8 %iv, %N 78 call void @use(i1 %t.1) 79 %t.2 = icmp sge i8 %iv, %N 80 call void @use(i1 %t.2) 81 %f.1 = icmp ult i8 %iv, %N 82 call void @use(i1 %f.1) 83 %f.2 = icmp slt i8 %iv, %N 84 call void @use(i1 %f.2) 85 %c.0 = icmp ugt i8 %iv, 2 86 call void @use(i1 %c.0) 87 %iv.next = add nsw nuw i8 %iv, 1 88 br label %loop.header 89 90exit.1: 91 ret void 92} 93 94define void @iv_known_non_negative_iv_variable_trip_count_uge_operands_swapped(i8 %N) { 95; CHECK-LABEL: @iv_known_non_negative_iv_variable_trip_count_uge_operands_swapped( 96; CHECK-NEXT: entry: 97; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 98; CHECK: loop.header: 99; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 100; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[N:%.*]], [[IV]] 101; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]] 102; CHECK: loop.latch: 103; CHECK-NEXT: call void @use(i1 true) 104; CHECK-NEXT: [[T_2:%.*]] = icmp sge i8 [[N]], [[IV]] 105; CHECK-NEXT: call void @use(i1 [[T_2]]) 106; CHECK-NEXT: call void @use(i1 false) 107; CHECK-NEXT: [[F_2:%.*]] = icmp slt i8 [[N]], [[IV]] 108; CHECK-NEXT: call void @use(i1 [[F_2]]) 109; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 110; CHECK-NEXT: br label [[LOOP_HEADER]] 111; CHECK: exit.1: 112; CHECK-NEXT: ret void 113; 114entry: 115 br label %loop.header 116 117loop.header: 118 %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop.latch ] 119 %cmp = icmp uge i8 %N, %iv 120 br i1 %cmp, label %loop.latch, label %exit.1 121 122loop.latch: 123 %t.1 = icmp uge i8 %N, %iv 124 call void @use(i1 %t.1) 125 %t.2 = icmp sge i8 %N, %iv 126 call void @use(i1 %t.2) 127 %f.1 = icmp ult i8 %N, %iv 128 call void @use(i1 %f.1) 129 %f.2 = icmp slt i8 %N, %iv 130 call void @use(i1 %f.2) 131 %iv.next = add nsw nuw i8 %iv, 1 132 br label %loop.header 133 134exit.1: 135 ret void 136} 137 138define void @iv_known_non_negative_iv_variable_trip_count_ugt(i8 %N) { 139; CHECK-LABEL: @iv_known_non_negative_iv_variable_trip_count_ugt( 140; CHECK-NEXT: entry: 141; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 142; CHECK: loop.header: 143; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 144; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[IV]], [[N:%.*]] 145; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]] 146; CHECK: loop.latch: 147; CHECK-NEXT: call void @use(i1 true) 148; CHECK-NEXT: call void @use(i1 true) 149; CHECK-NEXT: call void @use(i1 false) 150; CHECK-NEXT: call void @use(i1 false) 151; CHECK-NEXT: [[C_0:%.*]] = icmp ugt i8 [[IV]], 2 152; CHECK-NEXT: call void @use(i1 [[C_0]]) 153; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 154; CHECK-NEXT: br label [[LOOP_HEADER]] 155; CHECK: exit.1: 156; CHECK-NEXT: ret void 157; 158entry: 159 br label %loop.header 160 161loop.header: 162 %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop.latch ] 163 %cmp = icmp ugt i8 %iv, %N 164 br i1 %cmp, label %loop.latch, label %exit.1 165 166loop.latch: 167 %t.1 = icmp ugt i8 %iv, %N 168 call void @use(i1 %t.1) 169 %t.2 = icmp sgt i8 %iv, %N 170 call void @use(i1 %t.2) 171 %f.1 = icmp ult i8 %iv, %N 172 call void @use(i1 %f.1) 173 %f.2 = icmp slt i8 %iv, %N 174 call void @use(i1 %f.2) 175 %c.0 = icmp ugt i8 %iv, 2 176 call void @use(i1 %c.0) 177 %iv.next = add nsw nuw i8 %iv, 1 178 br label %loop.header 179 180exit.1: 181 ret void 182} 183 184define void @iv_known_non_negative_iv_variable_trip_count_ugt_operands_swapped(i8 %N) { 185; CHECK-LABEL: @iv_known_non_negative_iv_variable_trip_count_ugt_operands_swapped( 186; CHECK-NEXT: entry: 187; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 188; CHECK: loop.header: 189; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 190; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N:%.*]], [[IV]] 191; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]] 192; CHECK: loop.latch: 193; CHECK-NEXT: call void @use(i1 true) 194; CHECK-NEXT: [[T_2:%.*]] = icmp sgt i8 [[N]], [[IV]] 195; CHECK-NEXT: call void @use(i1 [[T_2]]) 196; CHECK-NEXT: call void @use(i1 false) 197; CHECK-NEXT: [[F_2:%.*]] = icmp slt i8 [[N]], [[IV]] 198; CHECK-NEXT: call void @use(i1 [[F_2]]) 199; CHECK-NEXT: [[C_0:%.*]] = icmp ugt i8 [[IV]], 2 200; CHECK-NEXT: call void @use(i1 [[C_0]]) 201; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 202; CHECK-NEXT: br label [[LOOP_HEADER]] 203; CHECK: exit.1: 204; CHECK-NEXT: ret void 205; 206entry: 207 br label %loop.header 208 209loop.header: 210 %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop.latch ] 211 %cmp = icmp ugt i8 %N, %iv 212 br i1 %cmp, label %loop.latch, label %exit.1 213 214loop.latch: 215 %t.1 = icmp ugt i8 %N, %iv 216 call void @use(i1 %t.1) 217 %t.2 = icmp sgt i8 %N, %iv 218 call void @use(i1 %t.2) 219 %f.1 = icmp ult i8 %N, %iv 220 call void @use(i1 %f.1) 221 %f.2 = icmp slt i8 %N, %iv 222 call void @use(i1 %f.2) 223 %c.0 = icmp ugt i8 %iv, 2 224 call void @use(i1 %c.0) 225 %iv.next = add nsw nuw i8 %iv, 1 226 br label %loop.header 227 228exit.1: 229 ret void 230} 231