1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -indvars -S < %s | FileCheck %s 3 4; A collection of tests which domonstrate cases where we can use properties 5; of the loop (i.e. single exit, finite, mustprogress) to optimize conditions 6; and extends we couldn't otherwise handle. 7 8target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 9 10define void @slt_constant_rhs(i16 %n.raw, i8 %start) mustprogress { 11; CHECK-LABEL: @slt_constant_rhs( 12; CHECK-NEXT: entry: 13; CHECK-NEXT: br label [[FOR_BODY:%.*]] 14; CHECK: for.body: 15; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ] 16; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 17; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 18; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[ZEXT]], 254 19; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 20; CHECK: for.end: 21; CHECK-NEXT: ret void 22; 23entry: 24 br label %for.body 25 26for.body: ; preds = %entry, %for.body 27 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ] 28 %iv.next = add i8 %iv, 1 29 %zext = zext i8 %iv.next to i16 30 %cmp = icmp slt i16 %zext, 254 31 br i1 %cmp, label %for.body, label %for.end 32 33for.end: ; preds = %for.body, %entry 34 ret void 35} 36 37;; Range logic doesn't depend on must execute 38define void @slt_constant_rhs_maythrow(i16 %n.raw, i8 %start) mustprogress { 39; CHECK-LABEL: @slt_constant_rhs_maythrow( 40; CHECK-NEXT: entry: 41; CHECK-NEXT: br label [[FOR_BODY:%.*]] 42; CHECK: for.body: 43; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ] 44; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 45; CHECK-NEXT: call void @unknown() 46; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 47; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[ZEXT]], 254 48; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 49; CHECK: for.end: 50; CHECK-NEXT: ret void 51; 52entry: 53 br label %for.body 54 55for.body: ; preds = %entry, %for.body 56 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ] 57 %iv.next = add i8 %iv, 1 58 call void @unknown() 59 %zext = zext i8 %iv.next to i16 60 %cmp = icmp slt i16 %zext, 254 61 br i1 %cmp, label %for.body, label %for.end 62 63for.end: ; preds = %for.body, %entry 64 ret void 65} 66 67;; Range logic doesn't depend on must execute 68define void @slt_constant_rhs_multiexit(i16 %n.raw, i8 %start, i1 %c) mustprogress { 69; CHECK-LABEL: @slt_constant_rhs_multiexit( 70; CHECK-NEXT: entry: 71; CHECK-NEXT: br label [[FOR_BODY:%.*]] 72; CHECK: for.body: 73; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ [[START:%.*]], [[ENTRY:%.*]] ] 74; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 75; CHECK-NEXT: br i1 [[C:%.*]], label [[LATCH]], label [[FOR_END:%.*]] 76; CHECK: latch: 77; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 78; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[ZEXT]], 254 79; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]] 80; CHECK: for.end: 81; CHECK-NEXT: ret void 82; 83entry: 84 br label %for.body 85 86for.body: ; preds = %entry, %for.body 87 %iv = phi i8 [ %iv.next, %latch ], [ %start, %entry ] 88 %iv.next = add i8 %iv, 1 89 br i1 %c, label %latch, label %for.end 90 91latch: 92 %zext = zext i8 %iv.next to i16 93 %cmp = icmp slt i16 %zext, 254 94 br i1 %cmp, label %for.body, label %for.end 95 96for.end: ; preds = %for.body, %entry 97 ret void 98} 99 100define void @slt_non_constant_rhs(i16 %n) mustprogress { 101; CHECK-LABEL: @slt_non_constant_rhs( 102; CHECK-NEXT: entry: 103; CHECK-NEXT: br label [[FOR_BODY:%.*]] 104; CHECK: for.body: 105; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 106; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 107; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 108; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[ZEXT]], [[N:%.*]] 109; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 110; CHECK: for.end: 111; CHECK-NEXT: ret void 112; 113entry: 114 br label %for.body 115 116for.body: ; preds = %entry, %for.body 117 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 118 %iv.next = add i8 %iv, 1 119 %zext = zext i8 %iv.next to i16 120 %cmp = icmp slt i16 %zext, %n 121 br i1 %cmp, label %for.body, label %for.end 122 123for.end: ; preds = %for.body, %entry 124 ret void 125} 126 127; Case where we could prove this using range facts, but not must exit reasoning 128define void @slt_non_constant_rhs_no_mustprogress(i16 %n.raw) { 129; CHECK-LABEL: @slt_non_constant_rhs_no_mustprogress( 130; CHECK-NEXT: entry: 131; CHECK-NEXT: [[N:%.*]] = and i16 [[N_RAW:%.*]], 255 132; CHECK-NEXT: br label [[FOR_BODY:%.*]] 133; CHECK: for.body: 134; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 135; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 136; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 137; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[ZEXT]], [[N]] 138; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 139; CHECK: for.end: 140; CHECK-NEXT: ret void 141; 142entry: 143 %n = and i16 %n.raw, 255 144 br label %for.body 145 146for.body: ; preds = %entry, %for.body 147 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 148 %iv.next = add i8 %iv, 1 149 %zext = zext i8 %iv.next to i16 150 %cmp = icmp slt i16 %zext, %n 151 br i1 %cmp, label %for.body, label %for.end 152 153for.end: ; preds = %for.body, %entry 154 ret void 155} 156 157@G = external global i8 158 159; Negative case where the loop could be infinite and make progress 160define void @slt_neg_well_defined_infinite(i16 %n) mustprogress { 161; CHECK-LABEL: @slt_neg_well_defined_infinite( 162; CHECK-NEXT: entry: 163; CHECK-NEXT: br label [[FOR_BODY:%.*]] 164; CHECK: for.body: 165; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 166; CHECK-NEXT: store volatile i8 [[IV]], i8* @G, align 1 167; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 168; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 169; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[ZEXT]], [[N:%.*]] 170; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 171; CHECK: for.end: 172; CHECK-NEXT: ret void 173; 174entry: 175 br label %for.body 176 177for.body: ; preds = %entry, %for.body 178 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 179 store volatile i8 %iv, i8* @G 180 %iv.next = add i8 %iv, 1 181 %zext = zext i8 %iv.next to i16 182 %cmp = icmp slt i16 %zext, %n 183 br i1 %cmp, label %for.body, label %for.end 184 185for.end: ; preds = %for.body, %entry 186 ret void 187} 188 189; Negative case with no mustprogress rsltuirement 190define void @slt_neg_no_mustprogress(i16 %n) { 191; CHECK-LABEL: @slt_neg_no_mustprogress( 192; CHECK-NEXT: entry: 193; CHECK-NEXT: br label [[FOR_BODY:%.*]] 194; CHECK: for.body: 195; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 196; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 197; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 198; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[ZEXT]], [[N:%.*]] 199; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 200; CHECK: for.end: 201; CHECK-NEXT: ret void 202; 203entry: 204 br label %for.body 205 206for.body: ; preds = %entry, %for.body 207 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 208 %iv.next = add i8 %iv, 1 209 %zext = zext i8 %iv.next to i16 210 %cmp = icmp slt i16 %zext, %n 211 br i1 %cmp, label %for.body, label %for.end 212 213for.end: ; preds = %for.body, %entry 214 ret void 215} 216 217declare void @unknown() 218 219define void @slt_neg_abnormal_exit(i16 %n) mustprogress { 220; CHECK-LABEL: @slt_neg_abnormal_exit( 221; CHECK-NEXT: entry: 222; CHECK-NEXT: br label [[FOR_BODY:%.*]] 223; CHECK: for.body: 224; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 225; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 226; CHECK-NEXT: call void @unknown() 227; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 228; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[ZEXT]], [[N:%.*]] 229; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 230; CHECK: for.end: 231; CHECK-NEXT: ret void 232; 233entry: 234 br label %for.body 235 236for.body: ; preds = %entry, %for.body 237 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 238 %iv.next = add i8 %iv, 1 239 call void @unknown() 240 %zext = zext i8 %iv.next to i16 241 %cmp = icmp slt i16 %zext, %n 242 br i1 %cmp, label %for.body, label %for.end 243 244for.end: ; preds = %for.body, %entry 245 ret void 246} 247 248; For the other comparison flavors, we only bother to repeat the positive 249; tests since the negative variants are mostly the same. 250 251define void @ne_constant_rhs(i16 %n.raw, i8 %start) mustprogress { 252; CHECK-LABEL: @ne_constant_rhs( 253; CHECK-NEXT: entry: 254; CHECK-NEXT: br label [[FOR_BODY:%.*]] 255; CHECK: for.body: 256; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ] 257; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 258; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 259; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[ZEXT]], 254 260; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 261; CHECK: for.end: 262; CHECK-NEXT: ret void 263; 264entry: 265 br label %for.body 266 267for.body: ; preds = %entry, %for.body 268 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ] 269 %iv.next = add i8 %iv, 1 270 %zext = zext i8 %iv.next to i16 271 %cmp = icmp ne i16 %zext, 254 272 br i1 %cmp, label %for.body, label %for.end 273 274for.end: ; preds = %for.body, %entry 275 ret void 276} 277 278define void @ne_non_constant_rhs(i16 %n) mustprogress { 279; CHECK-LABEL: @ne_non_constant_rhs( 280; CHECK-NEXT: entry: 281; CHECK-NEXT: br label [[FOR_BODY:%.*]] 282; CHECK: for.body: 283; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 284; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 285; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 286; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[ZEXT]], [[N:%.*]] 287; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 288; CHECK: for.end: 289; CHECK-NEXT: ret void 290; 291entry: 292 br label %for.body 293 294for.body: ; preds = %entry, %for.body 295 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 296 %iv.next = add i8 %iv, 1 297 %zext = zext i8 %iv.next to i16 298 %cmp = icmp ne i16 %zext, %n 299 br i1 %cmp, label %for.body, label %for.end 300 301for.end: ; preds = %for.body, %entry 302 ret void 303} 304 305define void @eq_constant_rhs(i16 %n.raw, i8 %start) mustprogress { 306; CHECK-LABEL: @eq_constant_rhs( 307; CHECK-NEXT: entry: 308; CHECK-NEXT: br label [[FOR_BODY:%.*]] 309; CHECK: for.body: 310; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ] 311; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 312; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 313; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[ZEXT]], 254 314; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 315; CHECK: for.end: 316; CHECK-NEXT: ret void 317; 318entry: 319 br label %for.body 320 321for.body: ; preds = %entry, %for.body 322 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ] 323 %iv.next = add i8 %iv, 1 324 %zext = zext i8 %iv.next to i16 325 %cmp = icmp eq i16 %zext, 254 326 br i1 %cmp, label %for.body, label %for.end 327 328for.end: ; preds = %for.body, %entry 329 ret void 330} 331 332define void @eq_non_constant_rhs(i16 %n) mustprogress { 333; CHECK-LABEL: @eq_non_constant_rhs( 334; CHECK-NEXT: entry: 335; CHECK-NEXT: br label [[FOR_BODY:%.*]] 336; CHECK: for.body: 337; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 338; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 339; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 340; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[ZEXT]], [[N:%.*]] 341; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 342; CHECK: for.end: 343; CHECK-NEXT: ret void 344; 345entry: 346 br label %for.body 347 348for.body: ; preds = %entry, %for.body 349 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 350 %iv.next = add i8 %iv, 1 351 %zext = zext i8 %iv.next to i16 352 %cmp = icmp eq i16 %zext, %n 353 br i1 %cmp, label %for.body, label %for.end 354 355for.end: ; preds = %for.body, %entry 356 ret void 357} 358 359define void @sgt_constant_rhs(i16 %n.raw, i8 %start) mustprogress { 360; CHECK-LABEL: @sgt_constant_rhs( 361; CHECK-NEXT: entry: 362; CHECK-NEXT: br label [[FOR_BODY:%.*]] 363; CHECK: for.body: 364; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ] 365; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 366; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 367; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i16 [[ZEXT]], 254 368; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 369; CHECK: for.end: 370; CHECK-NEXT: ret void 371; 372entry: 373 br label %for.body 374 375for.body: ; preds = %entry, %for.body 376 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ] 377 %iv.next = add i8 %iv, 1 378 %zext = zext i8 %iv.next to i16 379 %cmp = icmp sgt i16 %zext, 254 380 br i1 %cmp, label %for.body, label %for.end 381 382for.end: ; preds = %for.body, %entry 383 ret void 384} 385 386define void @sgt_non_constant_rhs(i16 %n) mustprogress { 387; CHECK-LABEL: @sgt_non_constant_rhs( 388; CHECK-NEXT: entry: 389; CHECK-NEXT: br label [[FOR_BODY:%.*]] 390; CHECK: for.body: 391; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 392; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 393; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 394; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[ZEXT]], [[N:%.*]] 395; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 396; CHECK: for.end: 397; CHECK-NEXT: ret void 398; 399entry: 400 br label %for.body 401 402for.body: ; preds = %entry, %for.body 403 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 404 %iv.next = add i8 %iv, 1 405 %zext = zext i8 %iv.next to i16 406 %cmp = icmp sgt i16 %zext, %n 407 br i1 %cmp, label %for.body, label %for.end 408 409for.end: ; preds = %for.body, %entry 410 ret void 411} 412 413define void @sle_constant_rhs(i16 %n.raw, i8 %start) mustprogress { 414; CHECK-LABEL: @sle_constant_rhs( 415; CHECK-NEXT: entry: 416; CHECK-NEXT: br label [[FOR_BODY:%.*]] 417; CHECK: for.body: 418; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ] 419; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 420; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 421; CHECK-NEXT: [[CMP:%.*]] = icmp ule i16 [[ZEXT]], 254 422; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 423; CHECK: for.end: 424; CHECK-NEXT: ret void 425; 426entry: 427 br label %for.body 428 429for.body: ; preds = %entry, %for.body 430 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ] 431 %iv.next = add i8 %iv, 1 432 %zext = zext i8 %iv.next to i16 433 %cmp = icmp sle i16 %zext, 254 434 br i1 %cmp, label %for.body, label %for.end 435 436for.end: ; preds = %for.body, %entry 437 ret void 438} 439 440define void @sle_non_constant_rhs(i16 %n) mustprogress { 441; CHECK-LABEL: @sle_non_constant_rhs( 442; CHECK-NEXT: entry: 443; CHECK-NEXT: br label [[FOR_BODY:%.*]] 444; CHECK: for.body: 445; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 446; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 447; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 448; CHECK-NEXT: [[CMP:%.*]] = icmp sle i16 [[ZEXT]], [[N:%.*]] 449; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 450; CHECK: for.end: 451; CHECK-NEXT: ret void 452; 453entry: 454 br label %for.body 455 456for.body: ; preds = %entry, %for.body 457 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 458 %iv.next = add i8 %iv, 1 459 %zext = zext i8 %iv.next to i16 460 %cmp = icmp sle i16 %zext, %n 461 br i1 %cmp, label %for.body, label %for.end 462 463for.end: ; preds = %for.body, %entry 464 ret void 465} 466 467define void @sge_constant_rhs(i16 %n.raw, i8 %start) mustprogress { 468; CHECK-LABEL: @sge_constant_rhs( 469; CHECK-NEXT: entry: 470; CHECK-NEXT: br label [[FOR_BODY:%.*]] 471; CHECK: for.body: 472; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ] 473; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 474; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 475; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[ZEXT]], 254 476; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 477; CHECK: for.end: 478; CHECK-NEXT: ret void 479; 480entry: 481 br label %for.body 482 483for.body: ; preds = %entry, %for.body 484 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ] 485 %iv.next = add i8 %iv, 1 486 %zext = zext i8 %iv.next to i16 487 %cmp = icmp sge i16 %zext, 254 488 br i1 %cmp, label %for.body, label %for.end 489 490for.end: ; preds = %for.body, %entry 491 ret void 492} 493 494define void @sge_non_constant_rhs(i16 %n) mustprogress { 495; CHECK-LABEL: @sge_non_constant_rhs( 496; CHECK-NEXT: entry: 497; CHECK-NEXT: br label [[FOR_BODY:%.*]] 498; CHECK: for.body: 499; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 500; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 501; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 502; CHECK-NEXT: [[CMP:%.*]] = icmp sge i16 [[ZEXT]], [[N:%.*]] 503; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 504; CHECK: for.end: 505; CHECK-NEXT: ret void 506; 507entry: 508 br label %for.body 509 510for.body: ; preds = %entry, %for.body 511 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 512 %iv.next = add i8 %iv, 1 513 %zext = zext i8 %iv.next to i16 514 %cmp = icmp sge i16 %zext, %n 515 br i1 %cmp, label %for.body, label %for.end 516 517for.end: ; preds = %for.body, %entry 518 ret void 519} 520 521define void @ult_constant_rhs(i16 %n.raw, i8 %start) mustprogress { 522; CHECK-LABEL: @ult_constant_rhs( 523; CHECK-NEXT: entry: 524; CHECK-NEXT: br label [[FOR_BODY:%.*]] 525; CHECK: for.body: 526; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ] 527; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 528; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 529; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[ZEXT]], 254 530; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 531; CHECK: for.end: 532; CHECK-NEXT: ret void 533; 534entry: 535 br label %for.body 536 537for.body: ; preds = %entry, %for.body 538 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ] 539 %iv.next = add i8 %iv, 1 540 %zext = zext i8 %iv.next to i16 541 %cmp = icmp ult i16 %zext, 254 542 br i1 %cmp, label %for.body, label %for.end 543 544for.end: ; preds = %for.body, %entry 545 ret void 546} 547 548define void @ult_non_constant_rhs(i16 %n) mustprogress { 549; CHECK-LABEL: @ult_non_constant_rhs( 550; CHECK-NEXT: entry: 551; CHECK-NEXT: br label [[FOR_BODY:%.*]] 552; CHECK: for.body: 553; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 554; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 555; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 556; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[ZEXT]], [[N:%.*]] 557; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 558; CHECK: for.end: 559; CHECK-NEXT: ret void 560; 561entry: 562 br label %for.body 563 564for.body: ; preds = %entry, %for.body 565 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 566 %iv.next = add i8 %iv, 1 567 %zext = zext i8 %iv.next to i16 568 %cmp = icmp ult i16 %zext, %n 569 br i1 %cmp, label %for.body, label %for.end 570 571for.end: ; preds = %for.body, %entry 572 ret void 573} 574 575define void @ugt_constant_rhs(i16 %n.raw, i8 %start) mustprogress { 576; CHECK-LABEL: @ugt_constant_rhs( 577; CHECK-NEXT: entry: 578; CHECK-NEXT: br label [[FOR_BODY:%.*]] 579; CHECK: for.body: 580; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ] 581; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 582; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 583; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i16 [[ZEXT]], 254 584; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 585; CHECK: for.end: 586; CHECK-NEXT: ret void 587; 588entry: 589 br label %for.body 590 591for.body: ; preds = %entry, %for.body 592 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ] 593 %iv.next = add i8 %iv, 1 594 %zext = zext i8 %iv.next to i16 595 %cmp = icmp ugt i16 %zext, 254 596 br i1 %cmp, label %for.body, label %for.end 597 598for.end: ; preds = %for.body, %entry 599 ret void 600} 601 602define void @ugt_non_constant_rhs(i16 %n) mustprogress { 603; CHECK-LABEL: @ugt_non_constant_rhs( 604; CHECK-NEXT: entry: 605; CHECK-NEXT: br label [[FOR_BODY:%.*]] 606; CHECK: for.body: 607; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 608; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 609; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 610; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i16 [[ZEXT]], [[N:%.*]] 611; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 612; CHECK: for.end: 613; CHECK-NEXT: ret void 614; 615entry: 616 br label %for.body 617 618for.body: ; preds = %entry, %for.body 619 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 620 %iv.next = add i8 %iv, 1 621 %zext = zext i8 %iv.next to i16 622 %cmp = icmp ugt i16 %zext, %n 623 br i1 %cmp, label %for.body, label %for.end 624 625for.end: ; preds = %for.body, %entry 626 ret void 627} 628 629define void @ule_constant_rhs(i16 %n.raw, i8 %start) mustprogress { 630; CHECK-LABEL: @ule_constant_rhs( 631; CHECK-NEXT: entry: 632; CHECK-NEXT: br label [[FOR_BODY:%.*]] 633; CHECK: for.body: 634; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ] 635; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 636; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 637; CHECK-NEXT: [[CMP:%.*]] = icmp ule i16 [[ZEXT]], 254 638; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 639; CHECK: for.end: 640; CHECK-NEXT: ret void 641; 642entry: 643 br label %for.body 644 645for.body: ; preds = %entry, %for.body 646 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ] 647 %iv.next = add i8 %iv, 1 648 %zext = zext i8 %iv.next to i16 649 %cmp = icmp ule i16 %zext, 254 650 br i1 %cmp, label %for.body, label %for.end 651 652for.end: ; preds = %for.body, %entry 653 ret void 654} 655 656define void @ule_non_constant_rhs(i16 %n) mustprogress { 657; CHECK-LABEL: @ule_non_constant_rhs( 658; CHECK-NEXT: entry: 659; CHECK-NEXT: br label [[FOR_BODY:%.*]] 660; CHECK: for.body: 661; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 662; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 663; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 664; CHECK-NEXT: [[CMP:%.*]] = icmp ule i16 [[ZEXT]], [[N:%.*]] 665; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 666; CHECK: for.end: 667; CHECK-NEXT: ret void 668; 669entry: 670 br label %for.body 671 672for.body: ; preds = %entry, %for.body 673 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 674 %iv.next = add i8 %iv, 1 675 %zext = zext i8 %iv.next to i16 676 %cmp = icmp ule i16 %zext, %n 677 br i1 %cmp, label %for.body, label %for.end 678 679for.end: ; preds = %for.body, %entry 680 ret void 681} 682 683define void @uge_constant_rhs(i16 %n.raw, i8 %start) mustprogress { 684; CHECK-LABEL: @uge_constant_rhs( 685; CHECK-NEXT: entry: 686; CHECK-NEXT: br label [[FOR_BODY:%.*]] 687; CHECK: for.body: 688; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[START:%.*]], [[ENTRY:%.*]] ] 689; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 690; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 691; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[ZEXT]], 254 692; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 693; CHECK: for.end: 694; CHECK-NEXT: ret void 695; 696entry: 697 br label %for.body 698 699for.body: ; preds = %entry, %for.body 700 %iv = phi i8 [ %iv.next, %for.body ], [ %start, %entry ] 701 %iv.next = add i8 %iv, 1 702 %zext = zext i8 %iv.next to i16 703 %cmp = icmp uge i16 %zext, 254 704 br i1 %cmp, label %for.body, label %for.end 705 706for.end: ; preds = %for.body, %entry 707 ret void 708} 709 710define void @uge_non_constant_rhs(i16 %n) mustprogress { 711; CHECK-LABEL: @uge_non_constant_rhs( 712; CHECK-NEXT: entry: 713; CHECK-NEXT: br label [[FOR_BODY:%.*]] 714; CHECK: for.body: 715; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 716; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1 717; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV_NEXT]] to i16 718; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[ZEXT]], [[N:%.*]] 719; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 720; CHECK: for.end: 721; CHECK-NEXT: ret void 722; 723entry: 724 br label %for.body 725 726for.body: ; preds = %entry, %for.body 727 %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ] 728 %iv.next = add i8 %iv, 1 729 %zext = zext i8 %iv.next to i16 730 %cmp = icmp uge i16 %zext, %n 731 br i1 %cmp, label %for.body, label %for.end 732 733for.end: ; preds = %for.body, %entry 734 ret void 735} 736