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(i8) 8declare void @use.i1(i1) 9declare void @llvm.assume(i1) 10declare i1 @cond() 11 12define void @test_iv_wraps_1(i8 %len.n, i8 %a) { 13; CHECK-LABEL: @test_iv_wraps_1( 14; CHECK-NEXT: loop.ph: 15; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 16; CHECK: loop.header: 17; CHECK-NEXT: [[IV:%.*]] = phi i8 [ -1, [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 18; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], 1 19; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[LOOP_LATCH]] 20; CHECK: loop.latch: 21; CHECK-NEXT: [[T_1:%.*]] = icmp uge i8 [[IV]], -1 22; CHECK-NEXT: call void @use.i1(i1 [[T_1]]) 23; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 24; CHECK-NEXT: br label [[LOOP_HEADER]] 25; CHECK: exit: 26; CHECK-NEXT: ret void 27; 28loop.ph: 29 br label %loop.header 30 31loop.header: 32 %iv = phi i8 [ 255, %loop.ph ], [ %iv.next, %loop.latch ] 33 %c = icmp eq i8 %iv, 1 34 br i1 %c, label %exit, label %loop.latch 35 36loop.latch: 37 %t.1 = icmp uge i8 %iv, 255 38 call void @use.i1(i1 %t.1) 39 %iv.next = add i8 %iv, 1 40 br label %loop.header 41 42exit: 43 ret void 44} 45 46define void @test_iv_nuw_nsw_1_uge_start(i8 %len.n, i8 %a) { 47; CHECK-LABEL: @test_iv_nuw_nsw_1_uge_start( 48; CHECK-NEXT: loop.ph: 49; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 50; CHECK: loop.header: 51; CHECK-NEXT: [[IV:%.*]] = phi i8 [ -1, [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 52; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], 1 53; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 54; CHECK: for.body: 55; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() 56; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]] 57; CHECK: loop.latch: 58; CHECK-NEXT: call void @use.i1(i1 true) 59; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 60; CHECK-NEXT: br label [[LOOP_HEADER]] 61; CHECK: exit: 62; CHECK-NEXT: ret void 63; 64loop.ph: 65 br label %loop.header 66 67loop.header: 68 %iv = phi i8 [ 255, %loop.ph ], [ %iv.next, %loop.latch ] 69 %c = icmp eq i8 %iv, 1 70 br i1 %c, label %exit, label %for.body 71 72for.body: 73 %c.2 = call i1 @cond() 74 br i1 %c.2, label %loop.latch, label %exit 75 76loop.latch: 77 %t.1 = icmp uge i8 %iv, 255 78 call void @use.i1(i1 %t.1) 79 %iv.next = add nsw nuw i8 %iv, 1 80 br label %loop.header 81 82exit: 83 ret void 84} 85 86define void @test_iv_nuw_nsw_2_uge_start(i8 %len.n, i8 %a) { 87; CHECK-LABEL: @test_iv_nuw_nsw_2_uge_start( 88; CHECK-NEXT: loop.ph: 89; CHECK-NEXT: [[START:%.*]] = add i8 -2, 1 90; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 91; CHECK: loop.header: 92; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[START]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 93; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], 1 94; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 95; CHECK: for.body: 96; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() 97; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]] 98; CHECK: loop.latch: 99; CHECK-NEXT: call void @use.i1(i1 true) 100; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 101; CHECK-NEXT: br label [[LOOP_HEADER]] 102; CHECK: exit: 103; CHECK-NEXT: ret void 104; 105loop.ph: 106 %start = add i8 254, 1 107 br label %loop.header 108 109loop.header: 110 %iv = phi i8 [ %start, %loop.ph ], [ %iv.next, %loop.latch ] 111 %c = icmp eq i8 %iv, 1 112 br i1 %c, label %exit, label %for.body 113 114for.body: 115 %c.2 = call i1 @cond() 116 br i1 %c.2, label %loop.latch, label %exit 117 118loop.latch: 119 %t.1 = icmp uge i8 %iv, 255 120 call void @use.i1(i1 %t.1) 121 %iv.next = add nsw nuw i8 %iv, 1 122 br label %loop.header 123 124exit: 125 ret void 126} 127 128define void @test_iv_nsw_nuw_1_ult_end(i8 %len.n, i8 %a) { 129; CHECK-LABEL: @test_iv_nsw_nuw_1_ult_end( 130; CHECK-NEXT: loop.ph: 131; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 132; CHECK: loop.header: 133; CHECK-NEXT: [[IV:%.*]] = phi i8 [ -2, [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 134; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], 1 135; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 136; CHECK: for.body: 137; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() 138; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]] 139; CHECK: loop.latch: 140; CHECK-NEXT: call void @use.i1(i1 false) 141; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 142; CHECK-NEXT: br label [[LOOP_HEADER]] 143; CHECK: exit: 144; CHECK-NEXT: ret void 145; 146loop.ph: 147 br label %loop.header 148 149loop.header: 150 %iv = phi i8 [ 254, %loop.ph ], [ %iv.next, %loop.latch ] 151 %c = icmp eq i8 %iv, 1 152 br i1 %c, label %exit, label %for.body 153 154for.body: 155 %c.2 = call i1 @cond() 156 br i1 %c.2, label %loop.latch, label %exit 157 158loop.latch: 159 %t.1 = icmp ult i8 %iv, 1 160 call void @use.i1(i1 %t.1) 161 %iv.next = add nsw nuw i8 %iv, 1 162 br label %loop.header 163 164exit: 165 ret void 166} 167 168 169define void @test_iv_nsw_nuw_2_ult_end(i8 %len.n, i8 %a, i8 %b) { 170; CHECK-LABEL: @test_iv_nsw_nuw_2_ult_end( 171; CHECK-NEXT: loop.ph: 172; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 173; CHECK: loop.header: 174; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[A:%.*]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 175; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], [[B:%.*]] 176; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 177; CHECK: for.body: 178; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() 179; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]] 180; CHECK: loop.latch: 181; CHECK-NEXT: [[T_1:%.*]] = icmp ult i8 [[IV]], [[B]] 182; CHECK-NEXT: call void @use.i1(i1 [[T_1]]) 183; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 184; CHECK-NEXT: br label [[LOOP_HEADER]] 185; CHECK: exit: 186; CHECK-NEXT: ret void 187; 188loop.ph: 189 br label %loop.header 190 191loop.header: 192 %iv = phi i8 [ %a, %loop.ph ], [ %iv.next, %loop.latch ] 193 %c = icmp eq i8 %iv, %b 194 br i1 %c, label %exit, label %for.body 195 196for.body: 197 %c.2 = call i1 @cond() 198 br i1 %c.2, label %loop.latch, label %exit 199 200loop.latch: 201 %t.1 = icmp ult i8 %iv, %b 202 call void @use.i1(i1 %t.1) 203 %iv.next = add nsw nuw i8 %iv, 1 204 br label %loop.header 205 206exit: 207 ret void 208} 209 210define void @test_iv_nsw_nuw_3_ult_start_var(i8 %len.n, i8 %a, i8 %b) { 211; CHECK-LABEL: @test_iv_nsw_nuw_3_ult_start_var( 212; CHECK-NEXT: loop.ph: 213; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 214; CHECK: loop.header: 215; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[A:%.*]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 216; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], [[B:%.*]] 217; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 218; CHECK: for.body: 219; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() 220; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]] 221; CHECK: loop.latch: 222; CHECK-NEXT: call void @use.i1(i1 false) 223; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1 224; CHECK-NEXT: br label [[LOOP_HEADER]] 225; CHECK: exit: 226; CHECK-NEXT: ret void 227; 228loop.ph: 229 br label %loop.header 230 231loop.header: 232 %iv = phi i8 [ %a, %loop.ph ], [ %iv.next, %loop.latch ] 233 %c = icmp eq i8 %iv, %b 234 br i1 %c, label %exit, label %for.body 235 236for.body: 237 %c.2 = call i1 @cond() 238 br i1 %c.2, label %loop.latch, label %exit 239 240loop.latch: 241 %t.1 = icmp ult i8 %iv, %a 242 call void @use.i1(i1 %t.1) 243 %iv.next = add nsw nuw i8 %iv, 1 244 br label %loop.header 245 246exit: 247 ret void 248} 249 250define void @test_iv_nsw_nuw_inc_2_ult_start_var(i8 %len.n, i8 %a, i8 %b) { 251; CHECK-LABEL: @test_iv_nsw_nuw_inc_2_ult_start_var( 252; CHECK-NEXT: loop.ph: 253; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 254; CHECK: loop.header: 255; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[A:%.*]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 256; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[IV]], [[B:%.*]] 257; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 258; CHECK: for.body: 259; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() 260; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]] 261; CHECK: loop.latch: 262; CHECK-NEXT: call void @use.i1(i1 false) 263; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 2 264; CHECK-NEXT: br label [[LOOP_HEADER]] 265; CHECK: exit: 266; CHECK-NEXT: ret void 267; 268loop.ph: 269 br label %loop.header 270 271loop.header: 272 %iv = phi i8 [ %a, %loop.ph ], [ %iv.next, %loop.latch ] 273 %c = icmp eq i8 %iv, %b 274 br i1 %c, label %exit, label %for.body 275 276for.body: 277 %c.2 = call i1 @cond() 278 br i1 %c.2, label %loop.latch, label %exit 279 280loop.latch: 281 %t.1 = icmp ult i8 %iv, %a 282 call void @use.i1(i1 %t.1) 283 %iv.next = add nsw nuw i8 %iv, 2 284 br label %loop.header 285 286exit: 287 ret void 288} 289