Home | History | Annotate | Download | only in IndVarSimplify
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; RUN: opt -indvars -S < %s | FileCheck %s
      3 
      4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
      5 target triple = "x86_64-unknown-linux-gnu"
      6 
      7 ; General case: without extra knowledge, trunc cannot be eliminated.
      8 define 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 ;
     22 entry:
     23   br label %loop
     24 loop:
     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
     30 exit:
     31   ret void
     32 }
     33 
     34 
     35 define 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 ;
     49 entry:
     50   br label %loop
     51 loop:
     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
     57 exit:
     58   ret void
     59 }
     60 
     61 ; Max value at which we can eliminate trunc: SINT_MAX - 1.
     62 define 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 ;
     76 entry:
     77   br label %loop
     78 loop:
     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
     84 exit:
     85   ret void
     86 }
     87 
     88 ; If we start from SINT_MAX then the predicate is always false.
     89 define 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 ;
     99 entry:
    100   br label %loop
    101 loop:
    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
    107 exit:
    108   ret void
    109 }
    110 
    111 ; Minimum value at which we can apply the transform: SINT_MIN + 1.
    112 define 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 ;
    126 entry:
    127   br label %loop
    128 loop:
    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
    134 exit:
    135   ret void
    136 }
    137 
    138 ; FIXME: Harmful LFTR should be thrown away.
    139 define 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 ;
    154 entry:
    155   br label %loop
    156 loop:
    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
    162 exit:
    163   ret void
    164 }
    165 
    166 ; Trunc changes the actual value of the IV, so it is invalid to remove it: SINT_MIN - 1.
    167 define 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 ;
    181 entry:
    182   br label %loop
    183 loop:
    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
    189 exit:
    190   ret void
    191 }
    192 
    193 ; General case: without extra knowledge, trunc cannot be eliminated.
    194 define 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 ;
    207 entry:
    208   br label %loop
    209 loop:
    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
    215 exit:
    216   ret void
    217 }
    218 
    219 ; FIXME: Harmful LFTR should be thrown away.
    220 define 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 ;
    234 entry:
    235   br label %loop
    236 loop:
    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
    242 exit:
    243   ret void
    244 }
    245 
    246 ; Max value at which we can eliminate trunc: UINT_MAX - 1.
    247 define 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 ;
    260 entry:
    261   br label %loop
    262 loop:
    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
    268 exit:
    269   ret void
    270 }
    271 
    272 ; If we start from UINT_MAX then the predicate is always false.
    273 define 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 ;
    282 entry:
    283   br label %loop
    284 loop:
    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
    290 exit:
    291   ret void
    292 }
    293 
    294 ; Minimum value at which we can apply the transform: UINT_MIN.
    295 define 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 ;
    309 entry:
    310   br label %loop
    311 loop:
    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
    317 exit:
    318   ret void
    319 }
    320 
    321 ; Start from 1.
    322 define 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 ;
    335 entry:
    336   br label %loop
    337 loop:
    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
    343 exit:
    344   ret void
    345 }
    346 
    347 ; Trunc changes the actual value of the IV, so it is invalid to remove it: UINT_MIN - 1.
    348 define 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 ;
    361 entry:
    362   br label %loop
    363 loop:
    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
    369 exit:
    370   ret void
    371 }
    372 
    373 ; Do not eliminate trunc if it is used by something different from icmp.
    374 define 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 ;
    388 entry:
    389   br label %loop
    390 loop:
    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
    397 exit:
    398   ret void
    399 }
    400 
    401 ; Check that we can eliminate both signed and unsigned compare.
    402 define 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 ;
    418 entry:
    419   br label %loop
    420 loop:
    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
    428 exit:
    429   ret void
    430 }
    431 
    432 ; Widen NE as unsigned.
    433 define 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 ;
    446 entry:
    447   br label %loop
    448 loop:
    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
    454 exit:
    455   ret void
    456 }
    457 
    458 ; Widen NE as signed.
    459 define 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 ;
    474 entry:
    475   br label %loop
    476 loop:
    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
    484 exit:
    485   ret void
    486 }
    487 
    488 define 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 
    509 bb1:                                              ; preds = %bb6, %0
    510   %e.5.0 = phi i32 [ 0, %0 ], [ %_tmp32, %bb6 ]
    511   br i1 undef, label %bb2, label %bb6
    512 
    513 bb2:                                              ; preds = %bb1
    514   %_tmp15 = trunc i32 %e.5.0 to i16
    515   br i1 undef, label %bb3, label %bb4
    516 
    517 bb3:                                              ; preds = %bb2
    518   br label %bb4
    519 
    520 bb4:                                              ; preds = %bb3, %bb2
    521   br label %bb6
    522 
    523 bb5:                                              ; preds = %bb5, %bb5
    524   %_tmp24 = icmp slt i16 %_tmp15, 0
    525   br i1 %_tmp24, label %bb5, label %bb5
    526 
    527 bb6:                                              ; preds = %bb4, %bb1
    528   %_tmp32 = add nuw nsw i32 %e.5.0, 1
    529   br i1 false, label %bb1, label %bb7
    530 
    531 bb7:                                             ; 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.
    537 define 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 ;
    551 entry:
    552   %n = load i32, i32* %p, !range !0
    553   br label %loop
    554 loop:
    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
    560 exit:
    561   ret void
    562 }
    563 
    564 !0 = !{i32 0, i32 1000}
    565