1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3 4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 5 6 7declare void @use(i16) 8declare void @llvm.assume(i1) 9 10define void @test_monotonic_ptr_iv_inc_1_eq_to_uge(i8 %len.n, i16 %a) { 11; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge( 12; CHECK-NEXT: entry: 13; CHECK-NEXT: [[LEN:%.*]] = zext i8 [[LEN_N:%.*]] to i16 14; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp uge i16 [[LEN]], [[A:%.*]] 15; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 16; CHECK: loop.ph: 17; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 18; CHECK: loop.header: 19; CHECK-NEXT: [[IV:%.*]] = phi i16 [ 0, [[LOOP_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 20; CHECK-NEXT: [[C:%.*]] = icmp eq i16 [[IV]], [[LEN]] 21; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 22; CHECK: for.body: 23; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 24; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 25; CHECK: loop.latch: 26; CHECK-NEXT: call void @use(i16 [[IV]]) 27; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1 28; CHECK-NEXT: br label [[LOOP_HEADER]] 29; CHECK: exit: 30; CHECK-NEXT: ret void 31; 32entry: 33 %len = zext i8 %len.n to i16 34 %len.neg = icmp uge i16 %len, %a 35 br i1 %len.neg, label %exit, label %loop.ph 36 37loop.ph: 38 br label %loop.header 39 40loop.header: 41 %iv = phi i16 [ 0, %loop.ph ], [ %iv.next, %loop.latch ] 42 %c = icmp eq i16 %iv, %len 43 br i1 %c, label %exit, label %for.body 44 45for.body: 46 %t.1 = icmp uge i16 %iv, 0 47 %t.2 = icmp ult i16 %iv, %a 48 %and = and i1 %t.1, %t.2 49 br i1 %and, label %loop.latch, label %exit 50 51loop.latch: 52 call void @use(i16 %iv) 53 %iv.next = add nuw nsw i16 %iv, 1 54 br label %loop.header 55 56exit: 57 ret void 58} 59 60define void @test_remove_check_with_incrementing_integer_induction(i8 %len.n, i16 %a) { 61; CHECK-LABEL: @test_remove_check_with_incrementing_integer_induction( 62; CHECK-NEXT: entry: 63; CHECK-NEXT: [[LEN:%.*]] = zext i8 [[LEN_N:%.*]] to i16 64; CHECK-NEXT: [[LEN_NEG_NOT:%.*]] = icmp ult i16 [[LEN]], [[A:%.*]] 65; CHECK-NEXT: br i1 [[LEN_NEG_NOT]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]] 66; CHECK: loop.header: 67; CHECK-NEXT: [[IV:%.*]] = phi i16 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] 68; CHECK-NEXT: [[C:%.*]] = icmp ne i16 [[IV]], [[LEN]] 69; CHECK-NEXT: [[T_2:%.*]] = icmp ult i16 [[IV]], [[A]] 70; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C]], [[T_2]] 71; CHECK-NEXT: br i1 [[OR_COND]], label [[LOOP_LATCH]], label [[EXIT]] 72; CHECK: loop.latch: 73; CHECK-NEXT: call void @use(i16 [[IV]]) 74; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1 75; CHECK-NEXT: br label [[LOOP_HEADER]] 76; CHECK: exit: 77; CHECK-NEXT: ret void 78; 79entry: 80 %len = zext i8 %len.n to i16 81 %len.neg.not = icmp ult i16 %len, %a 82 br i1 %len.neg.not, label %loop.header, label %exit 83 84loop.header: ; preds = %entry, %loop.latch 85 %iv = phi i16 [ %iv.next, %loop.latch ], [ 0, %entry ] 86 %c = icmp ne i16 %iv, %len 87 %t.2 = icmp ult i16 %iv, %a 88 %or.cond = and i1 %c, %t.2 89 br i1 %or.cond, label %loop.latch, label %exit 90 91loop.latch: ; preds = %loop.header 92 call void @use(i16 %iv) 93 %iv.next = add nuw nsw i16 %iv, 1 94 br label %loop.header 95 96exit: ; preds = %loop.header, %entry 97 ret void 98} 99 100define void @test_monotonic_ptr_iv_inc_2_eq_to_uge(i8 %len.n, i16 %a) { 101; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_eq_to_uge( 102; CHECK-NEXT: entry: 103; CHECK-NEXT: [[LEN:%.*]] = zext i8 [[LEN_N:%.*]] to i16 104; CHECK-NEXT: [[LEN_LT:%.*]] = icmp ult i16 [[LEN]], [[A:%.*]] 105; CHECK-NEXT: br i1 [[LEN_LT]], label [[LOOP_PH:%.*]], label [[EXIT:%.*]] 106; CHECK: loop.ph: 107; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 108; CHECK: loop.header: 109; CHECK-NEXT: [[IV:%.*]] = phi i16 [ 0, [[LOOP_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 110; CHECK-NEXT: [[C:%.*]] = icmp eq i16 [[IV]], [[LEN]] 111; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 112; CHECK: for.body: 113; CHECK-NEXT: [[T_2:%.*]] = icmp ult i16 [[IV]], [[A]] 114; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 115; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 116; CHECK: loop.latch: 117; CHECK-NEXT: call void @use(i16 [[IV]]) 118; CHECK-NEXT: [[IV_NEXT]] = add nuw i16 [[IV]], 2 119; CHECK-NEXT: br label [[LOOP_HEADER]] 120; CHECK: exit: 121; CHECK-NEXT: ret void 122; 123entry: 124 %len = zext i8 %len.n to i16 125 %len.lt = icmp ult i16 %len, %a 126 br i1 %len.lt, label %loop.ph, label %exit 127 128loop.ph: 129 br label %loop.header 130 131loop.header: 132 %iv = phi i16 [ 0, %loop.ph ], [ %iv.next, %loop.latch ] 133 %c = icmp eq i16 %iv, %len 134 br i1 %c, label %exit, label %for.body 135 136for.body: 137 %t.1 = icmp uge i16 %iv, 0 138 %t.2 = icmp ult i16 %iv, %a 139 %and = and i1 %t.1, %t.2 140 br i1 %and, label %loop.latch, label %exit 141 142loop.latch: 143 call void @use(i16 %iv) 144 %iv.next = add nuw i16 %iv, 2 145 br label %loop.header 146 147exit: 148 ret void 149} 150 151define void @test_monotonic_ptr_iv_inc_2_eq_to_uge_variable_start(i16 %start, i8 %len.n, i16 %a) { 152; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_eq_to_uge_variable_start( 153; CHECK-NEXT: entry: 154; CHECK-NEXT: [[LEN:%.*]] = zext i8 [[LEN_N:%.*]] to i16 155; CHECK-NEXT: [[LEN_LT:%.*]] = icmp ult i16 [[LEN]], [[A:%.*]] 156; CHECK-NEXT: [[START_LT:%.*]] = icmp ult i16 [[START:%.*]], [[LEN]] 157; CHECK-NEXT: [[AND_0:%.*]] = and i1 [[LEN_LT]], [[START_LT]] 158; CHECK-NEXT: br i1 [[AND_0]], label [[LOOP_PH:%.*]], label [[EXIT:%.*]] 159; CHECK: loop.ph: 160; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 161; CHECK: loop.header: 162; CHECK-NEXT: [[IV:%.*]] = phi i16 [ [[START]], [[LOOP_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 163; CHECK-NEXT: [[C:%.*]] = icmp eq i16 [[IV]], [[LEN]] 164; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 165; CHECK: for.body: 166; CHECK-NEXT: [[T_2:%.*]] = icmp ult i16 [[IV]], [[A]] 167; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 168; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 169; CHECK: loop.latch: 170; CHECK-NEXT: call void @use(i16 [[IV]]) 171; CHECK-NEXT: [[IV_NEXT]] = add nuw i16 [[IV]], 2 172; CHECK-NEXT: br label [[LOOP_HEADER]] 173; CHECK: exit: 174; CHECK-NEXT: ret void 175; 176entry: 177 %len = zext i8 %len.n to i16 178 %len.lt = icmp ult i16 %len, %a 179 %start.lt = icmp ult i16 %start, %len 180 %and.0 = and i1 %len.lt, %start.lt 181 br i1 %and.0, label %loop.ph, label %exit 182 183loop.ph: 184 br label %loop.header 185 186loop.header: 187 %iv = phi i16 [ %start, %loop.ph ], [ %iv.next, %loop.latch ] 188 %c = icmp eq i16 %iv, %len 189 br i1 %c, label %exit, label %for.body 190 191for.body: 192 %t.1 = icmp uge i16 %iv, 0 193 %t.2 = icmp ult i16 %iv, %a 194 %and = and i1 %t.1, %t.2 195 br i1 %and, label %loop.latch, label %exit 196 197loop.latch: 198 call void @use(i16 %iv) 199 %iv.next = add nuw i16 %iv, 2 200 br label %loop.header 201 202exit: 203 ret void 204} 205 206 207