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