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