1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -indvars -S < %s | FileCheck %s 3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 5target triple = "x86_64-unknown-linux-gnu" 6 7; General case: without extra knowledge, trunc cannot be eliminated. 8define void @test_00(i64 %start, i32 %n) { 9; 10; CHECK-LABEL: @test_00( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: br label [[LOOP:%.*]] 13; CHECK: loop: 14; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 15; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 16; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32 17; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[NARROW_IV]], [[N:%.*]] 18; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]] 19; CHECK: exit: 20; CHECK-NEXT: ret void 21; 22entry: 23 br label %loop 24loop: 25 %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] 26 %iv.next = add i64 %iv, 1 27 %narrow.iv = trunc i64 %iv to i32 28 %cmp = icmp slt i32 %narrow.iv, %n 29 br i1 %cmp, label %loop, label %exit 30exit: 31 ret void 32} 33 34 35define void @test_01(i32 %n) { 36; 37; CHECK-LABEL: @test_01( 38; CHECK-NEXT: entry: 39; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64 40; CHECK-NEXT: br label [[LOOP:%.*]] 41; CHECK: loop: 42; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 43; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 44; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]] 45; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]] 46; CHECK: exit: 47; CHECK-NEXT: ret void 48; 49entry: 50 br label %loop 51loop: 52 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 53 %iv.next = add i64 %iv, 1 54 %narrow.iv = trunc i64 %iv to i32 55 %cmp = icmp slt i32 %narrow.iv, %n 56 br i1 %cmp, label %loop, label %exit 57exit: 58 ret void 59} 60 61; Max value at which we can eliminate trunc: SINT_MAX - 1. 62define void @test_02(i32 %n) { 63; 64; CHECK-LABEL: @test_02( 65; CHECK-NEXT: entry: 66; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64 67; CHECK-NEXT: br label [[LOOP:%.*]] 68; CHECK: loop: 69; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 2147483646, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 70; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 71; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]] 72; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]] 73; CHECK: exit: 74; CHECK-NEXT: ret void 75; 76entry: 77 br label %loop 78loop: 79 %iv = phi i64 [ 2147483646, %entry ], [ %iv.next, %loop ] 80 %iv.next = add i64 %iv, 1 81 %narrow.iv = trunc i64 %iv to i32 82 %cmp = icmp slt i32 %narrow.iv, %n 83 br i1 %cmp, label %loop, label %exit 84exit: 85 ret void 86} 87 88; If we start from SINT_MAX then the predicate is always false. 89define void @test_03(i32 %n) { 90; 91; CHECK-LABEL: @test_03( 92; CHECK-NEXT: entry: 93; CHECK-NEXT: br label [[LOOP:%.*]] 94; CHECK: loop: 95; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]] 96; CHECK: exit: 97; CHECK-NEXT: ret void 98; 99entry: 100 br label %loop 101loop: 102 %iv = phi i64 [2147483647, %entry], [%iv.next, %loop] 103 %iv.next = add i64 %iv, 1 104 %narrow.iv = trunc i64 %iv to i32 105 %cmp = icmp slt i32 %narrow.iv, %n 106 br i1 %cmp, label %loop, label %exit 107exit: 108 ret void 109} 110 111; Minimum value at which we can apply the transform: SINT_MIN + 1. 112define void @test_04(i32 %n) { 113; 114; CHECK-LABEL: @test_04( 115; CHECK-NEXT: entry: 116; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64 117; CHECK-NEXT: br label [[LOOP:%.*]] 118; CHECK: loop: 119; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -2147483647, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 120; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1 121; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]] 122; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]] 123; CHECK: exit: 124; CHECK-NEXT: ret void 125; 126entry: 127 br label %loop 128loop: 129 %iv = phi i64 [ -2147483647, %entry ], [ %iv.next, %loop ] 130 %iv.next = add i64 %iv, 1 131 %narrow.iv = trunc i64 %iv to i32 132 %cmp = icmp slt i32 %narrow.iv, %n 133 br i1 %cmp, label %loop, label %exit 134exit: 135 ret void 136} 137 138; FIXME: Harmful LFTR should be thrown away. 139define void @test_05(i32 %n) { 140; 141; CHECK-LABEL: @test_05( 142; CHECK-NEXT: entry: 143; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1 144; CHECK-NEXT: br label [[LOOP:%.*]] 145; CHECK: loop: 146; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -2147483648, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 147; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1 148; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32 149; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]] 150; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] 151; CHECK: exit: 152; CHECK-NEXT: ret void 153; 154entry: 155 br label %loop 156loop: 157 %iv = phi i64 [ -2147483648, %entry ], [ %iv.next, %loop ] 158 %iv.next = add i64 %iv, 1 159 %narrow.iv = trunc i64 %iv to i32 160 %cmp = icmp slt i32 %narrow.iv, %n 161 br i1 %cmp, label %loop, label %exit 162exit: 163 ret void 164} 165 166; Trunc changes the actual value of the IV, so it is invalid to remove it: SINT_MIN - 1. 167define void @test_06(i32 %n) { 168; 169; CHECK-LABEL: @test_06( 170; CHECK-NEXT: entry: 171; CHECK-NEXT: br label [[LOOP:%.*]] 172; CHECK: loop: 173; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -2147483649, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 174; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 175; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32 176; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[NARROW_IV]], [[N:%.*]] 177; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]] 178; CHECK: exit: 179; CHECK-NEXT: ret void 180; 181entry: 182 br label %loop 183loop: 184 %iv = phi i64 [ -2147483649, %entry ], [ %iv.next, %loop ] 185 %iv.next = add i64 %iv, 1 186 %narrow.iv = trunc i64 %iv to i32 187 %cmp = icmp slt i32 %narrow.iv, %n 188 br i1 %cmp, label %loop, label %exit 189exit: 190 ret void 191} 192 193; General case: without extra knowledge, trunc cannot be eliminated. 194define void @test_00_unsigned(i64 %start, i32 %n) { 195; CHECK-LABEL: @test_00_unsigned( 196; CHECK-NEXT: entry: 197; CHECK-NEXT: br label [[LOOP:%.*]] 198; CHECK: loop: 199; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 200; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 201; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32 202; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[NARROW_IV]], [[N:%.*]] 203; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]] 204; CHECK: exit: 205; CHECK-NEXT: ret void 206; 207entry: 208 br label %loop 209loop: 210 %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] 211 %iv.next = add i64 %iv, 1 212 %narrow.iv = trunc i64 %iv to i32 213 %cmp = icmp ult i32 %narrow.iv, %n 214 br i1 %cmp, label %loop, label %exit 215exit: 216 ret void 217} 218 219; FIXME: Harmful LFTR should be thrown away. 220define void @test_01_unsigned(i32 %n) { 221; CHECK-LABEL: @test_01_unsigned( 222; CHECK-NEXT: entry: 223; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1 224; CHECK-NEXT: br label [[LOOP:%.*]] 225; CHECK: loop: 226; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 227; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 228; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32 229; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]] 230; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] 231; CHECK: exit: 232; CHECK-NEXT: ret void 233; 234entry: 235 br label %loop 236loop: 237 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 238 %iv.next = add i64 %iv, 1 239 %narrow.iv = trunc i64 %iv to i32 240 %cmp = icmp ult i32 %narrow.iv, %n 241 br i1 %cmp, label %loop, label %exit 242exit: 243 ret void 244} 245 246; Max value at which we can eliminate trunc: UINT_MAX - 1. 247define void @test_02_unsigned(i32 %n) { 248; CHECK-LABEL: @test_02_unsigned( 249; CHECK-NEXT: entry: 250; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64 251; CHECK-NEXT: br label [[LOOP:%.*]] 252; CHECK: loop: 253; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 4294967294, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 254; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 255; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]] 256; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]] 257; CHECK: exit: 258; CHECK-NEXT: ret void 259; 260entry: 261 br label %loop 262loop: 263 %iv = phi i64 [ 4294967294, %entry ], [ %iv.next, %loop ] 264 %iv.next = add i64 %iv, 1 265 %narrow.iv = trunc i64 %iv to i32 266 %cmp = icmp ult i32 %narrow.iv, %n 267 br i1 %cmp, label %loop, label %exit 268exit: 269 ret void 270} 271 272; If we start from UINT_MAX then the predicate is always false. 273define void @test_03_unsigned(i32 %n) { 274; CHECK-LABEL: @test_03_unsigned( 275; CHECK-NEXT: entry: 276; CHECK-NEXT: br label [[LOOP:%.*]] 277; CHECK: loop: 278; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]] 279; CHECK: exit: 280; CHECK-NEXT: ret void 281; 282entry: 283 br label %loop 284loop: 285 %iv = phi i64 [ 4294967295, %entry ], [ %iv.next, %loop ] 286 %iv.next = add i64 %iv, 1 287 %narrow.iv = trunc i64 %iv to i32 288 %cmp = icmp ult i32 %narrow.iv, %n 289 br i1 %cmp, label %loop, label %exit 290exit: 291 ret void 292} 293 294; Minimum value at which we can apply the transform: UINT_MIN. 295define void @test_04_unsigned(i32 %n) { 296; CHECK-LABEL: @test_04_unsigned( 297; CHECK-NEXT: entry: 298; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1 299; CHECK-NEXT: br label [[LOOP:%.*]] 300; CHECK: loop: 301; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 302; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 303; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32 304; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]] 305; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] 306; CHECK: exit: 307; CHECK-NEXT: ret void 308; 309entry: 310 br label %loop 311loop: 312 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 313 %iv.next = add i64 %iv, 1 314 %narrow.iv = trunc i64 %iv to i32 315 %cmp = icmp ult i32 %narrow.iv, %n 316 br i1 %cmp, label %loop, label %exit 317exit: 318 ret void 319} 320 321; Start from 1. 322define void @test_05_unsigned(i32 %n) { 323; CHECK-LABEL: @test_05_unsigned( 324; CHECK-NEXT: entry: 325; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64 326; CHECK-NEXT: br label [[LOOP:%.*]] 327; CHECK: loop: 328; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 329; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 330; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]] 331; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]] 332; CHECK: exit: 333; CHECK-NEXT: ret void 334; 335entry: 336 br label %loop 337loop: 338 %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ] 339 %iv.next = add i64 %iv, 1 340 %narrow.iv = trunc i64 %iv to i32 341 %cmp = icmp ult i32 %narrow.iv, %n 342 br i1 %cmp, label %loop, label %exit 343exit: 344 ret void 345} 346 347; Trunc changes the actual value of the IV, so it is invalid to remove it: UINT_MIN - 1. 348define void @test_06_unsigned(i32 %n) { 349; CHECK-LABEL: @test_06_unsigned( 350; CHECK-NEXT: entry: 351; CHECK-NEXT: br label [[LOOP:%.*]] 352; CHECK: loop: 353; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 354; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1 355; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32 356; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[NARROW_IV]], [[N:%.*]] 357; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]] 358; CHECK: exit: 359; CHECK-NEXT: ret void 360; 361entry: 362 br label %loop 363loop: 364 %iv = phi i64 [ -1, %entry ], [ %iv.next, %loop ] 365 %iv.next = add i64 %iv, 1 366 %narrow.iv = trunc i64 %iv to i32 367 %cmp = icmp ult i32 %narrow.iv, %n 368 br i1 %cmp, label %loop, label %exit 369exit: 370 ret void 371} 372 373; Do not eliminate trunc if it is used by something different from icmp. 374define void @test_07(i32* %p, i32 %n) { 375; CHECK-LABEL: @test_07( 376; CHECK-NEXT: entry: 377; CHECK-NEXT: br label [[LOOP:%.*]] 378; CHECK: loop: 379; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 380; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 381; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32 382; CHECK-NEXT: store i32 [[NARROW_IV]], i32* [[P:%.*]] 383; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[NARROW_IV]], [[N:%.*]] 384; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]] 385; CHECK: exit: 386; CHECK-NEXT: ret void 387; 388entry: 389 br label %loop 390loop: 391 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 392 %iv.next = add i64 %iv, 1 393 %narrow.iv = trunc i64 %iv to i32 394 store i32 %narrow.iv, i32* %p 395 %cmp = icmp slt i32 %narrow.iv, %n 396 br i1 %cmp, label %loop, label %exit 397exit: 398 ret void 399} 400 401; Check that we can eliminate both signed and unsigned compare. 402define void @test_08(i32 %n) { 403; CHECK-LABEL: @test_08( 404; CHECK-NEXT: entry: 405; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64 406; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N]] to i64 407; CHECK-NEXT: br label [[LOOP:%.*]] 408; CHECK: loop: 409; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 410; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 411; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]] 412; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IV]], [[ZEXT]] 413; CHECK-NEXT: [[CMP:%.*]] = and i1 [[TMP0]], [[TMP1]] 414; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]] 415; CHECK: exit: 416; CHECK-NEXT: ret void 417; 418entry: 419 br label %loop 420loop: 421 %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ] 422 %iv.next = add i64 %iv, 1 423 %narrow.iv = trunc i64 %iv to i32 424 %cmp1 = icmp slt i32 %narrow.iv, %n 425 %cmp2 = icmp ult i32 %narrow.iv, %n 426 %cmp = and i1 %cmp1, %cmp2 427 br i1 %cmp, label %loop, label %exit 428exit: 429 ret void 430} 431 432; Widen NE as unsigned. 433define void @test_09(i32 %n) { 434; CHECK-LABEL: @test_09( 435; CHECK-NEXT: entry: 436; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64 437; CHECK-NEXT: br label [[LOOP:%.*]] 438; CHECK: loop: 439; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 440; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 441; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV]], [[ZEXT]] 442; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]] 443; CHECK: exit: 444; CHECK-NEXT: ret void 445; 446entry: 447 br label %loop 448loop: 449 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 450 %iv.next = add i64 %iv, 1 451 %narrow.iv = trunc i64 %iv to i32 452 %cmp = icmp ne i32 %narrow.iv, %n 453 br i1 %cmp, label %loop, label %exit 454exit: 455 ret void 456} 457 458; Widen NE as signed. 459define void @test_10(i32 %n) { 460; CHECK-LABEL: @test_10( 461; CHECK-NEXT: entry: 462; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[N:%.*]] to i64 463; CHECK-NEXT: br label [[LOOP:%.*]] 464; CHECK: loop: 465; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -100, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 466; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 467; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV]], [[SEXT]] 468; CHECK-NEXT: [[NEGCMP:%.*]] = icmp slt i64 [[IV]], -10 469; CHECK-NEXT: [[CMP:%.*]] = and i1 [[TMP0]], [[NEGCMP]] 470; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]] 471; CHECK: exit: 472; CHECK-NEXT: ret void 473; 474entry: 475 br label %loop 476loop: 477 %iv = phi i64 [ -100, %entry ], [ %iv.next, %loop ] 478 %iv.next = add i64 %iv, 1 479 %narrow.iv = trunc i64 %iv to i32 480 %trunccmp = icmp ne i32 %narrow.iv, %n 481 %negcmp = icmp slt i64 %iv, -10 482 %cmp = and i1 %trunccmp, %negcmp 483 br i1 %cmp, label %loop, label %exit 484exit: 485 ret void 486} 487 488define void @test_11() { 489; CHECK-LABEL: @test_11( 490; CHECK-NEXT: br label [[BB1:%.*]] 491; CHECK: bb1: 492; CHECK-NEXT: br i1 undef, label [[BB2:%.*]], label [[BB6:%.*]] 493; CHECK: bb2: 494; CHECK-NEXT: br i1 undef, label [[BB3:%.*]], label [[BB4:%.*]] 495; CHECK: bb3: 496; CHECK-NEXT: br label [[BB4]] 497; CHECK: bb4: 498; CHECK-NEXT: br label [[BB6]] 499; CHECK: bb5: 500; CHECK-NEXT: [[_TMP24:%.*]] = icmp slt i16 undef, 0 501; CHECK-NEXT: br i1 [[_TMP24]], label [[BB5:%.*]], label [[BB5]] 502; CHECK: bb6: 503; CHECK-NEXT: br i1 false, label [[BB1]], label [[BB7:%.*]] 504; CHECK: bb7: 505; CHECK-NEXT: ret void 506; 507 br label %bb1 508 509bb1: ; preds = %bb6, %0 510 %e.5.0 = phi i32 [ 0, %0 ], [ %_tmp32, %bb6 ] 511 br i1 undef, label %bb2, label %bb6 512 513bb2: ; preds = %bb1 514 %_tmp15 = trunc i32 %e.5.0 to i16 515 br i1 undef, label %bb3, label %bb4 516 517bb3: ; preds = %bb2 518 br label %bb4 519 520bb4: ; preds = %bb3, %bb2 521 br label %bb6 522 523bb5: ; preds = %bb5, %bb5 524 %_tmp24 = icmp slt i16 %_tmp15, 0 525 br i1 %_tmp24, label %bb5, label %bb5 526 527bb6: ; preds = %bb4, %bb1 528 %_tmp32 = add nuw nsw i32 %e.5.0, 1 529 br i1 false, label %bb1, label %bb7 530 531bb7: ; preds = %bb6 532 ret void 533} 534 535; Show that we can turn signed comparison to unsigned and use zext while 536; comparing non-negative values. 537define void @test_12(i32* %p) { 538; CHECK-LABEL: @test_12( 539; CHECK-NEXT: entry: 540; CHECK-NEXT: [[N:%.*]] = load i32, i32* [[P:%.*]], !range !0 541; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[N]] to i64 542; CHECK-NEXT: br label [[LOOP:%.*]] 543; CHECK: loop: 544; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 545; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 546; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV_NEXT]], [[ZEXT]] 547; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]] 548; CHECK: exit: 549; CHECK-NEXT: ret void 550; 551entry: 552 %n = load i32, i32* %p, !range !0 553 br label %loop 554loop: 555 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 556 %iv.next = add i64 %iv, 1 557 %narrow.iv = trunc i64 %iv.next to i32 558 %cmp = icmp slt i32 %narrow.iv, %n 559 br i1 %cmp, label %loop, label %exit 560exit: 561 ret void 562} 563 564!0 = !{i32 0, i32 1000} 565