1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt -S -passes=constraint-elimination < %s | FileCheck %s 3 4declare void @use(i1) 5 6define void @signed_iv_step_1(i64 %end) { 7; CHECK-LABEL: define void @signed_iv_step_1( 8; CHECK-SAME: i64 [[END:%.*]]) { 9; CHECK-NEXT: entry: 10; CHECK-NEXT: [[PRECOND:%.*]] = icmp sge i64 [[END]], -10 11; CHECK-NEXT: br i1 [[PRECOND]], label [[LOOP:%.*]], label [[EXIT:%.*]] 12; CHECK: loop: 13; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ -10, [[ENTRY:%.*]] ] 14; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 15; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]] 16; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]] 17; CHECK: loop.latch: 18; CHECK-NEXT: call void @use(i1 true) 19; CHECK-NEXT: call void @use(i1 true) 20; CHECK-NEXT: br label [[LOOP]] 21; CHECK: exit: 22; CHECK-NEXT: ret void 23; 24entry: 25 %precond = icmp sge i64 %end, -10 26 br i1 %precond, label %loop, label %exit 27 28loop: 29 %iv = phi i64 [ %iv.next, %loop.latch ], [ -10, %entry ] 30 %iv.next = add i64 %iv, 1 31 %cmp.i.not = icmp eq i64 %iv, %end 32 br i1 %cmp.i.not, label %exit, label %loop.latch 33 34loop.latch: 35 %cmp2 = icmp slt i64 %iv, %end 36 call void @use(i1 %cmp2) 37 %cmp3 = icmp sge i64 %iv, -10 38 call void @use(i1 %cmp3) 39 br label %loop 40 41exit: 42 ret void 43} 44 45define void @signed_iv_step_4(i64 %count) { 46; CHECK-LABEL: define void @signed_iv_step_4( 47; CHECK-SAME: i64 [[COUNT:%.*]]) { 48; CHECK-NEXT: entry: 49; CHECK-NEXT: [[END:%.*]] = shl nsw i64 [[COUNT]], 2 50; CHECK-NEXT: [[PRECOND:%.*]] = icmp sgt i64 [[COUNT]], -1 51; CHECK-NEXT: br i1 [[PRECOND]], label [[LOOP:%.*]], label [[EXIT:%.*]] 52; CHECK: loop: 53; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] 54; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 4 55; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]] 56; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]] 57; CHECK: loop.latch: 58; CHECK-NEXT: call void @use(i1 true) 59; CHECK-NEXT: call void @use(i1 true) 60; CHECK-NEXT: br label [[LOOP]] 61; CHECK: exit: 62; CHECK-NEXT: ret void 63; 64entry: 65 %end = shl nsw i64 %count, 2 66 %precond = icmp sgt i64 %count, -1 67 br i1 %precond, label %loop, label %exit 68 69loop: 70 %iv = phi i64 [ %iv.next, %loop.latch ], [ 0, %entry ] 71 %iv.next = add i64 %iv, 4 72 %cmp.i.not = icmp eq i64 %iv, %end 73 br i1 %cmp.i.not, label %exit, label %loop.latch 74 75loop.latch: 76 %cmp2 = icmp slt i64 %iv, %end 77 call void @use(i1 %cmp2) 78 %cmp3 = icmp sge i64 %iv, 0 79 call void @use(i1 %cmp3) 80 br label %loop 81 82exit: 83 ret void 84} 85 86define void @signed_iv_step_4_missing_precond(i64 %count) { 87; CHECK-LABEL: define void @signed_iv_step_4_missing_precond( 88; CHECK-SAME: i64 [[COUNT:%.*]]) { 89; CHECK-NEXT: entry: 90; CHECK-NEXT: [[END:%.*]] = shl i64 [[COUNT]], 2 91; CHECK-NEXT: [[PRECOND:%.*]] = icmp sgt i64 [[COUNT]], -1 92; CHECK-NEXT: br i1 [[PRECOND]], label [[LOOP:%.*]], label [[EXIT:%.*]] 93; CHECK: loop: 94; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] 95; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 4 96; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]] 97; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]] 98; CHECK: loop.latch: 99; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[IV]], [[END]] 100; CHECK-NEXT: call void @use(i1 [[CMP2]]) 101; CHECK-NEXT: [[CMP3:%.*]] = icmp sge i64 [[IV]], 0 102; CHECK-NEXT: call void @use(i1 [[CMP3]]) 103; CHECK-NEXT: br label [[LOOP]] 104; CHECK: exit: 105; CHECK-NEXT: ret void 106; 107entry: 108 %end = shl i64 %count, 2 109 %precond = icmp sgt i64 %count, -1 110 br i1 %precond, label %loop, label %exit 111 112loop: 113 %iv = phi i64 [ %iv.next, %loop.latch ], [ 0, %entry ] 114 %iv.next = add i64 %iv, 4 115 %cmp.i.not = icmp eq i64 %iv, %end 116 br i1 %cmp.i.not, label %exit, label %loop.latch 117 118loop.latch: 119 %cmp2 = icmp slt i64 %iv, %end 120 call void @use(i1 %cmp2) 121 %cmp3 = icmp sge i64 %iv, 0 122 call void @use(i1 %cmp3) 123 br label %loop 124 125exit: 126 ret void 127} 128 129define void @signed_iv_step_4_start_4(i64 %count) { 130; CHECK-LABEL: define void @signed_iv_step_4_start_4( 131; CHECK-SAME: i64 [[COUNT:%.*]]) { 132; CHECK-NEXT: entry: 133; CHECK-NEXT: [[END:%.*]] = shl nsw i64 [[COUNT]], 2 134; CHECK-NEXT: [[PRECOND:%.*]] = icmp sgt i64 [[COUNT]], 0 135; CHECK-NEXT: br i1 [[PRECOND]], label [[LOOP:%.*]], label [[EXIT:%.*]] 136; CHECK: loop: 137; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 4, [[ENTRY:%.*]] ] 138; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 4 139; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]] 140; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]] 141; CHECK: loop.latch: 142; CHECK-NEXT: call void @use(i1 true) 143; CHECK-NEXT: call void @use(i1 true) 144; CHECK-NEXT: br label [[LOOP]] 145; CHECK: exit: 146; CHECK-NEXT: ret void 147; 148entry: 149 %end = shl nsw i64 %count, 2 150 %precond = icmp sgt i64 %count, 0 151 br i1 %precond, label %loop, label %exit 152 153loop: 154 %iv = phi i64 [ %iv.next, %loop.latch ], [ 4, %entry ] 155 %iv.next = add i64 %iv, 4 156 %cmp.i.not = icmp eq i64 %iv, %end 157 br i1 %cmp.i.not, label %exit, label %loop.latch 158 159loop.latch: 160 %cmp2 = icmp slt i64 %iv, %end 161 call void @use(i1 %cmp2) 162 %cmp3 = icmp sge i64 %iv, 4 163 call void @use(i1 %cmp3) 164 br label %loop 165 166exit: 167 ret void 168} 169 170define void @signed_iv_step_4_start_4_missing_precond(i64 %count) { 171; CHECK-LABEL: define void @signed_iv_step_4_start_4_missing_precond( 172; CHECK-SAME: i64 [[COUNT:%.*]]) { 173; CHECK-NEXT: entry: 174; CHECK-NEXT: [[END:%.*]] = shl nsw i64 [[COUNT]], 2 175; CHECK-NEXT: [[PRECOND:%.*]] = icmp sgt i64 [[COUNT]], -1 176; CHECK-NEXT: br i1 [[PRECOND]], label [[LOOP:%.*]], label [[EXIT:%.*]] 177; CHECK: loop: 178; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 4, [[ENTRY:%.*]] ] 179; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 4 180; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]] 181; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]] 182; CHECK: loop.latch: 183; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[IV]], [[END]] 184; CHECK-NEXT: call void @use(i1 [[CMP2]]) 185; CHECK-NEXT: [[CMP3:%.*]] = icmp sge i64 [[IV]], 4 186; CHECK-NEXT: call void @use(i1 [[CMP3]]) 187; CHECK-NEXT: br label [[LOOP]] 188; CHECK: exit: 189; CHECK-NEXT: ret void 190; 191entry: 192 %end = shl nsw i64 %count, 2 193 %precond = icmp sgt i64 %count, -1 194 br i1 %precond, label %loop, label %exit 195 196loop: 197 %iv = phi i64 [ %iv.next, %loop.latch ], [ 4, %entry ] 198 %iv.next = add i64 %iv, 4 199 %cmp.i.not = icmp eq i64 %iv, %end 200 br i1 %cmp.i.not, label %exit, label %loop.latch 201 202loop.latch: 203 %cmp2 = icmp slt i64 %iv, %end 204 call void @use(i1 %cmp2) 205 %cmp3 = icmp sge i64 %iv, 4 206 call void @use(i1 %cmp3) 207 br label %loop 208 209exit: 210 ret void 211} 212 213define void @signed_iv_step_minus1(i64 %end) { 214; CHECK-LABEL: define void @signed_iv_step_minus1( 215; CHECK-SAME: i64 [[END:%.*]]) { 216; CHECK-NEXT: entry: 217; CHECK-NEXT: [[PRECOND:%.*]] = icmp sle i64 [[END]], 10 218; CHECK-NEXT: br i1 [[PRECOND]], label [[LOOP:%.*]], label [[EXIT:%.*]] 219; CHECK: loop: 220; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 10, [[ENTRY:%.*]] ] 221; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], -1 222; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]] 223; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]] 224; CHECK: loop.latch: 225; CHECK-NEXT: call void @use(i1 true) 226; CHECK-NEXT: call void @use(i1 true) 227; CHECK-NEXT: br label [[LOOP]] 228; CHECK: exit: 229; CHECK-NEXT: ret void 230; 231entry: 232 %precond = icmp sle i64 %end, 10 233 br i1 %precond, label %loop, label %exit 234 235loop: 236 %iv = phi i64 [ %iv.next, %loop.latch ], [ 10, %entry ] 237 %iv.next = add i64 %iv, -1 238 %cmp.i.not = icmp eq i64 %iv, %end 239 br i1 %cmp.i.not, label %exit, label %loop.latch 240 241loop.latch: 242 %cmp2 = icmp sgt i64 %iv, %end 243 call void @use(i1 %cmp2) 244 %cmp3 = icmp sle i64 %iv, 10 245 call void @use(i1 %cmp3) 246 br label %loop 247 248exit: 249 ret void 250} 251 252define void @signed_iv_step_minus1_missing_precond(i64 %end) { 253; CHECK-LABEL: define void @signed_iv_step_minus1_missing_precond( 254; CHECK-SAME: i64 [[END:%.*]]) { 255; CHECK-NEXT: entry: 256; CHECK-NEXT: [[PRECOND:%.*]] = icmp sle i64 [[END]], 11 257; CHECK-NEXT: br i1 [[PRECOND]], label [[LOOP:%.*]], label [[EXIT:%.*]] 258; CHECK: loop: 259; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 10, [[ENTRY:%.*]] ] 260; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], -1 261; CHECK-NEXT: [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]] 262; CHECK-NEXT: br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]] 263; CHECK: loop.latch: 264; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[IV]], [[END]] 265; CHECK-NEXT: call void @use(i1 [[CMP2]]) 266; CHECK-NEXT: [[CMP3:%.*]] = icmp sle i64 [[IV]], 10 267; CHECK-NEXT: call void @use(i1 [[CMP3]]) 268; CHECK-NEXT: br label [[LOOP]] 269; CHECK: exit: 270; CHECK-NEXT: ret void 271; 272entry: 273 %precond = icmp sle i64 %end, 11 274 br i1 %precond, label %loop, label %exit 275 276loop: 277 %iv = phi i64 [ %iv.next, %loop.latch ], [ 10, %entry ] 278 %iv.next = add i64 %iv, -1 279 %cmp.i.not = icmp eq i64 %iv, %end 280 br i1 %cmp.i.not, label %exit, label %loop.latch 281 282loop.latch: 283 %cmp2 = icmp sgt i64 %iv, %end 284 call void @use(i1 %cmp2) 285 %cmp3 = icmp sle i64 %iv, 10 286 call void @use(i1 %cmp3) 287 br label %loop 288 289exit: 290 ret void 291} 292