Home | History | Annotate | Download | only in SystemZ
      1 ; Test that compares are ommitted if CC already has the right value
      2 ; (z10 version).
      3 ;
      4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
      5 
      6 declare void @foo()
      7 
      8 ; Addition provides enough for equality comparisons with zero.  First teest
      9 ; the EQ case.
     10 define i32 @f1(i32 %a, i32 %b, i32 *%dest) {
     11 ; CHECK-LABEL: f1:
     12 ; CHECK: afi %r2, 1000000
     13 ; CHECK-NEXT: je .L{{.*}}
     14 ; CHECK: br %r14
     15 entry:
     16   %res = add i32 %a, 1000000
     17   %cmp = icmp eq i32 %res, 0
     18   br i1 %cmp, label %exit, label %store
     19 
     20 store:
     21   store i32 %b, i32 *%dest
     22   br label %exit
     23 
     24 exit:
     25   ret i32 %res
     26 }
     27 
     28 ; ...and again with NE.
     29 define i32 @f2(i32 %a, i32 %b, i32 *%dest) {
     30 ; CHECK-LABEL: f2:
     31 ; CHECK: afi %r2, 1000000
     32 ; CHECK-NEXT: jne .L{{.*}}
     33 ; CHECK: br %r14
     34 entry:
     35   %res = add i32 %a, 1000000
     36   %cmp = icmp ne i32 %res, 0
     37   br i1 %cmp, label %exit, label %store
     38 
     39 store:
     40   store i32 %b, i32 *%dest
     41   br label %exit
     42 
     43 exit:
     44   ret i32 %res
     45 }
     46 
     47 ; SLT requires a comparison.
     48 define i32 @f3(i32 %a, i32 %b, i32 *%dest) {
     49 ; CHECK-LABEL: f3:
     50 ; CHECK: afi %r2, 1000000
     51 ; CHECK-NEXT: cijl %r2, 0, .L{{.*}}
     52 ; CHECK: br %r14
     53 entry:
     54   %res = add i32 %a, 1000000
     55   %cmp = icmp slt i32 %res, 0
     56   br i1 %cmp, label %exit, label %store
     57 
     58 store:
     59   store i32 %b, i32 *%dest
     60   br label %exit
     61 
     62 exit:
     63   ret i32 %res
     64 }
     65 
     66 ; ...SLE too.
     67 define i32 @f4(i32 %a, i32 %b, i32 *%dest) {
     68 ; CHECK-LABEL: f4:
     69 ; CHECK: afi %r2, 1000000
     70 ; CHECK-NEXT: cijle %r2, 0, .L{{.*}}
     71 ; CHECK: br %r14
     72 entry:
     73   %res = add i32 %a, 1000000
     74   %cmp = icmp sle i32 %res, 0
     75   br i1 %cmp, label %exit, label %store
     76 
     77 store:
     78   store i32 %b, i32 *%dest
     79   br label %exit
     80 
     81 exit:
     82   ret i32 %res
     83 }
     84 
     85 ; ...SGT too.
     86 define i32 @f5(i32 %a, i32 %b, i32 *%dest) {
     87 ; CHECK-LABEL: f5:
     88 ; CHECK: afi %r2, 1000000
     89 ; CHECK-NEXT: cijh %r2, 0, .L{{.*}}
     90 ; CHECK: br %r14
     91 entry:
     92   %res = add i32 %a, 1000000
     93   %cmp = icmp sgt i32 %res, 0
     94   br i1 %cmp, label %exit, label %store
     95 
     96 store:
     97   store i32 %b, i32 *%dest
     98   br label %exit
     99 
    100 exit:
    101   ret i32 %res
    102 }
    103 
    104 ; ...SGE too.
    105 define i32 @f6(i32 %a, i32 %b, i32 *%dest) {
    106 ; CHECK-LABEL: f6:
    107 ; CHECK: afi %r2, 1000000
    108 ; CHECK-NEXT: cijhe %r2, 0, .L{{.*}}
    109 ; CHECK: br %r14
    110 entry:
    111   %res = add i32 %a, 1000000
    112   %cmp = icmp sge i32 %res, 0
    113   br i1 %cmp, label %exit, label %store
    114 
    115 store:
    116   store i32 %b, i32 *%dest
    117   br label %exit
    118 
    119 exit:
    120   ret i32 %res
    121 }
    122 
    123 ; Subtraction also provides enough for equality comparisons with zero.
    124 define i32 @f7(i32 %a, i32 %b, i32 *%dest) {
    125 ; CHECK-LABEL: f7:
    126 ; CHECK: s %r2, 0(%r4)
    127 ; CHECK-NEXT: jne .L{{.*}}
    128 ; CHECK: br %r14
    129 entry:
    130   %cur = load i32 *%dest
    131   %res = sub i32 %a, %cur
    132   %cmp = icmp ne i32 %res, 0
    133   br i1 %cmp, label %exit, label %store
    134 
    135 store:
    136   store i32 %b, i32 *%dest
    137   br label %exit
    138 
    139 exit:
    140   ret i32 %res
    141 }
    142 
    143 ; ...but not for ordered comparisons.
    144 define i32 @f8(i32 %a, i32 %b, i32 *%dest) {
    145 ; CHECK-LABEL: f8:
    146 ; CHECK: s %r2, 0(%r4)
    147 ; CHECK-NEXT: cijl %r2, 0, .L{{.*}}
    148 ; CHECK: br %r14
    149 entry:
    150   %cur = load i32 *%dest
    151   %res = sub i32 %a, %cur
    152   %cmp = icmp slt i32 %res, 0
    153   br i1 %cmp, label %exit, label %store
    154 
    155 store:
    156   store i32 %b, i32 *%dest
    157   br label %exit
    158 
    159 exit:
    160   ret i32 %res
    161 }
    162 
    163 ; Logic register-register instructions also provide enough for equality
    164 ; comparisons with zero.
    165 define i32 @f9(i32 %a, i32 %b, i32 *%dest) {
    166 ; CHECK-LABEL: f9:
    167 ; CHECK: nr %r2, %r3
    168 ; CHECK-NEXT: jl .L{{.*}}
    169 ; CHECK: br %r14
    170 entry:
    171   %res = and i32 %a, %b
    172   %cmp = icmp ne i32 %res, 0
    173   br i1 %cmp, label %exit, label %store
    174 
    175 store:
    176   store i32 %b, i32 *%dest
    177   br label %exit
    178 
    179 exit:
    180   ret i32 %res
    181 }
    182 
    183 ; ...but not for ordered comparisons.
    184 define i32 @f10(i32 %a, i32 %b, i32 *%dest) {
    185 ; CHECK-LABEL: f10:
    186 ; CHECK: nr %r2, %r3
    187 ; CHECK-NEXT: cijl %r2, 0, .L{{.*}}
    188 ; CHECK: br %r14
    189 entry:
    190   %res = and i32 %a, %b
    191   %cmp = icmp slt i32 %res, 0
    192   br i1 %cmp, label %exit, label %store
    193 
    194 store:
    195   store i32 %b, i32 *%dest
    196   br label %exit
    197 
    198 exit:
    199   ret i32 %res
    200 }
    201 
    202 ; Logic register-immediate instructions also provide enough for equality
    203 ; comparisons with zero if the immediate covers the whole register.
    204 define i32 @f11(i32 %a, i32 %b, i32 *%dest) {
    205 ; CHECK-LABEL: f11:
    206 ; CHECK: nilf %r2, 100
    207 ; CHECK-NEXT: jl .L{{.*}}
    208 ; CHECK: br %r14
    209 entry:
    210   %res = and i32 %a, 100
    211   %cmp = icmp ne i32 %res, 0
    212   br i1 %cmp, label %exit, label %store
    213 
    214 store:
    215   store i32 %b, i32 *%dest
    216   br label %exit
    217 
    218 exit:
    219   ret i32 %res
    220 }
    221 
    222 ; Partial logic register-immediate instructions do not provide simple
    223 ; zero results.
    224 define i32 @f12(i32 %a, i32 %b, i32 *%dest) {
    225 ; CHECK-LABEL: f12:
    226 ; CHECK: nill %r2, 65436
    227 ; CHECK-NEXT: cijlh %r2, 0, .L{{.*}}
    228 ; CHECK: br %r14
    229 entry:
    230   %res = and i32 %a, -100
    231   %cmp = icmp ne i32 %res, 0
    232   br i1 %cmp, label %exit, label %store
    233 
    234 store:
    235   store i32 %b, i32 *%dest
    236   br label %exit
    237 
    238 exit:
    239   ret i32 %res
    240 }
    241 
    242 ; SRA provides the same CC result as a comparison with zero.
    243 define i32 @f13(i32 %a, i32 %b, i32 *%dest) {
    244 ; CHECK-LABEL: f13:
    245 ; CHECK: sra %r2, 0(%r3)
    246 ; CHECK-NEXT: je .L{{.*}}
    247 ; CHECK: br %r14
    248 entry:
    249   %res = ashr i32 %a, %b
    250   %cmp = icmp eq i32 %res, 0
    251   br i1 %cmp, label %exit, label %store
    252 
    253 store:
    254   store i32 %b, i32 *%dest
    255   br label %exit
    256 
    257 exit:
    258   ret i32 %res
    259 }
    260 
    261 ; ...and again with NE.
    262 define i32 @f14(i32 %a, i32 %b, i32 *%dest) {
    263 ; CHECK-LABEL: f14:
    264 ; CHECK: sra %r2, 0(%r3)
    265 ; CHECK-NEXT: jlh .L{{.*}}
    266 ; CHECK: br %r14
    267 entry:
    268   %res = ashr i32 %a, %b
    269   %cmp = icmp ne i32 %res, 0
    270   br i1 %cmp, label %exit, label %store
    271 
    272 store:
    273   store i32 %b, i32 *%dest
    274   br label %exit
    275 
    276 exit:
    277   ret i32 %res
    278 }
    279 
    280 ; ...and SLT.
    281 define i32 @f15(i32 %a, i32 %b, i32 *%dest) {
    282 ; CHECK-LABEL: f15:
    283 ; CHECK: sra %r2, 0(%r3)
    284 ; CHECK-NEXT: jl .L{{.*}}
    285 ; CHECK: br %r14
    286 entry:
    287   %res = ashr i32 %a, %b
    288   %cmp = icmp slt i32 %res, 0
    289   br i1 %cmp, label %exit, label %store
    290 
    291 store:
    292   store i32 %b, i32 *%dest
    293   br label %exit
    294 
    295 exit:
    296   ret i32 %res
    297 }
    298 
    299 ; ...and SLE.
    300 define i32 @f16(i32 %a, i32 %b, i32 *%dest) {
    301 ; CHECK-LABEL: f16:
    302 ; CHECK: sra %r2, 0(%r3)
    303 ; CHECK-NEXT: jle .L{{.*}}
    304 ; CHECK: br %r14
    305 entry:
    306   %res = ashr i32 %a, %b
    307   %cmp = icmp sle i32 %res, 0
    308   br i1 %cmp, label %exit, label %store
    309 
    310 store:
    311   store i32 %b, i32 *%dest
    312   br label %exit
    313 
    314 exit:
    315   ret i32 %res
    316 }
    317 
    318 ; ...and SGT.
    319 define i32 @f17(i32 %a, i32 %b, i32 *%dest) {
    320 ; CHECK-LABEL: f17:
    321 ; CHECK: sra %r2, 0(%r3)
    322 ; CHECK-NEXT: jh .L{{.*}}
    323 ; CHECK: br %r14
    324 entry:
    325   %res = ashr i32 %a, %b
    326   %cmp = icmp sgt i32 %res, 0
    327   br i1 %cmp, label %exit, label %store
    328 
    329 store:
    330   store i32 %b, i32 *%dest
    331   br label %exit
    332 
    333 exit:
    334   ret i32 %res
    335 }
    336 
    337 ; ...and SGE.
    338 define i32 @f18(i32 %a, i32 %b, i32 *%dest) {
    339 ; CHECK-LABEL: f18:
    340 ; CHECK: sra %r2, 0(%r3)
    341 ; CHECK-NEXT: jhe .L{{.*}}
    342 ; CHECK: br %r14
    343 entry:
    344   %res = ashr i32 %a, %b
    345   %cmp = icmp sge i32 %res, 0
    346   br i1 %cmp, label %exit, label %store
    347 
    348 store:
    349   store i32 %b, i32 *%dest
    350   br label %exit
    351 
    352 exit:
    353   ret i32 %res
    354 }
    355 
    356 ; RISBG provides the same result as a comparison against zero.
    357 ; Test the EQ case.
    358 define i64 @f19(i64 %a, i64 %b, i64 *%dest) {
    359 ; CHECK-LABEL: f19:
    360 ; CHECK: risbg %r2, %r3, 0, 190, 0
    361 ; CHECK-NEXT: je .L{{.*}}
    362 ; CHECK: br %r14
    363 entry:
    364   %res = and i64 %b, -2
    365   %cmp = icmp eq i64 %res, 0
    366   br i1 %cmp, label %exit, label %store
    367 
    368 store:
    369   store i64 %b, i64 *%dest
    370   br label %exit
    371 
    372 exit:
    373   ret i64 %res
    374 }
    375 
    376 ; ...and the SLT case.
    377 define i64 @f20(i64 %a, i64 %b, i64 *%dest) {
    378 ; CHECK-LABEL: f20:
    379 ; CHECK: risbg %r2, %r3, 0, 190, 0
    380 ; CHECK-NEXT: jl .L{{.*}}
    381 ; CHECK: br %r14
    382 entry:
    383   %res = and i64 %b, -2
    384   %cmp = icmp slt i64 %res, 0
    385   br i1 %cmp, label %exit, label %store
    386 
    387 store:
    388   store i64 %b, i64 *%dest
    389   br label %exit
    390 
    391 exit:
    392   ret i64 %res
    393 }
    394 
    395 ; Test a case where the register we're testing is set by a non-CC-clobbering
    396 ; instruction.
    397 define i32 @f21(i32 %a, i32 %b, i32 *%dest) {
    398 ; CHECK-LABEL: f21:
    399 ; CHECK: afi %r2, 1000000
    400 ; CHECK-NEXT: #APP
    401 ; CHECK-NEXT: blah %r2
    402 ; CHECK-NEXT: #NO_APP
    403 ; CHECK-NEXT: cije %r2, 0, .L{{.*}}
    404 ; CHECK: br %r14
    405 entry:
    406   %add = add i32 %a, 1000000
    407   %res = call i32 asm "blah $0", "=r,0" (i32 %add)
    408   %cmp = icmp eq i32 %res, 0
    409   br i1 %cmp, label %exit, label %store
    410 
    411 store:
    412   store i32 %b, i32 *%dest
    413   br label %exit
    414 
    415 exit:
    416   ret i32 %res
    417 }
    418 
    419 ; ...and again with a CC-clobbering instruction.
    420 define i32 @f22(i32 %a, i32 %b, i32 *%dest) {
    421 ; CHECK-LABEL: f22:
    422 ; CHECK: afi %r2, 1000000
    423 ; CHECK-NEXT: #APP
    424 ; CHECK-NEXT: blah %r2
    425 ; CHECK-NEXT: #NO_APP
    426 ; CHECK-NEXT: cije %r2, 0, .L{{.*}}
    427 ; CHECK: br %r14
    428 entry:
    429   %add = add i32 %a, 1000000
    430   %res = call i32 asm "blah $0", "=r,0,~{cc}" (i32 %add)
    431   %cmp = icmp eq i32 %res, 0
    432   br i1 %cmp, label %exit, label %store
    433 
    434 store:
    435   store i32 %b, i32 *%dest
    436   br label %exit
    437 
    438 exit:
    439   ret i32 %res
    440 }
    441 
    442 ; Check that stores do not interfere.
    443 define i32 @f23(i32 %a, i32 %b, i32 *%dest1, i32 *%dest2) {
    444 ; CHECK-LABEL: f23:
    445 ; CHECK: afi %r2, 1000000
    446 ; CHECK-NEXT: st %r2, 0(%r4)
    447 ; CHECK-NEXT: jne .L{{.*}}
    448 ; CHECK: br %r14
    449 entry:
    450   %res = add i32 %a, 1000000
    451   store i32 %res, i32 *%dest1
    452   %cmp = icmp ne i32 %res, 0
    453   br i1 %cmp, label %exit, label %store
    454 
    455 store:
    456   store i32 %b, i32 *%dest2
    457   br label %exit
    458 
    459 exit:
    460   ret i32 %res
    461 }
    462 
    463 ; Check that calls do interfere.
    464 define void @f24(i32 *%ptr) {
    465 ; CHECK-LABEL: f24:
    466 ; CHECK: afi [[REG:%r[0-9]+]], 1000000
    467 ; CHECK-NEXT: brasl %r14, foo@PLT
    468 ; CHECK-NEXT: cijlh [[REG]], 0, .L{{.*}}
    469 ; CHECK: br %r14
    470 entry:
    471   %val = load i32 *%ptr
    472   %xor = xor i32 %val, 1
    473   %add = add i32 %xor, 1000000
    474   call void @foo()
    475   %cmp = icmp ne i32 %add, 0
    476   br i1 %cmp, label %exit, label %store
    477 
    478 store:
    479   store i32 %add, i32 *%ptr
    480   br label %exit
    481 
    482 exit:
    483   ret void
    484 }
    485 
    486 ; Check that inline asms don't interfere if they don't clobber CC.
    487 define void @f25(i32 %a, i32 *%ptr) {
    488 ; CHECK-LABEL: f25:
    489 ; CHECK: afi %r2, 1000000
    490 ; CHECK-NEXT: #APP
    491 ; CHECK-NEXT: blah
    492 ; CHECK-NEXT: #NO_APP
    493 ; CHECK-NEXT: jne .L{{.*}}
    494 ; CHECK: br %r14
    495 entry:
    496   %add = add i32 %a, 1000000
    497   call void asm sideeffect "blah", "r"(i32 %add)
    498   %cmp = icmp ne i32 %add, 0
    499   br i1 %cmp, label %exit, label %store
    500 
    501 store:
    502   store i32 %add, i32 *%ptr
    503   br label %exit
    504 
    505 exit:
    506   ret void
    507 }
    508 
    509 ; ...but do interfere if they do clobber CC.
    510 define void @f26(i32 %a, i32 *%ptr) {
    511 ; CHECK-LABEL: f26:
    512 ; CHECK: afi %r2, 1000000
    513 ; CHECK-NEXT: #APP
    514 ; CHECK-NEXT: blah
    515 ; CHECK-NEXT: #NO_APP
    516 ; CHECK-NEXT: cijlh %r2, 0, .L{{.*}}
    517 ; CHECK: br %r14
    518 entry:
    519   %add = add i32 %a, 1000000
    520   call void asm sideeffect "blah", "r,~{cc}"(i32 %add)
    521   %cmp = icmp ne i32 %add, 0
    522   br i1 %cmp, label %exit, label %store
    523 
    524 store:
    525   store i32 %add, i32 *%ptr
    526   br label %exit
    527 
    528 exit:
    529   ret void
    530 }
    531 
    532 ; Test a case where CC is set based on a different register from the
    533 ; compare input.
    534 define i32 @f27(i32 %a, i32 %b, i32 *%dest1, i32 *%dest2) {
    535 ; CHECK-LABEL: f27:
    536 ; CHECK: afi %r2, 1000000
    537 ; CHECK-NEXT: sr %r3, %r2
    538 ; CHECK-NEXT: st %r3, 0(%r4)
    539 ; CHECK-NEXT: cije %r2, 0, .L{{.*}}
    540 ; CHECK: br %r14
    541 entry:
    542   %add = add i32 %a, 1000000
    543   %sub = sub i32 %b, %add
    544   store i32 %sub, i32 *%dest1
    545   %cmp = icmp eq i32 %add, 0
    546   br i1 %cmp, label %exit, label %store
    547 
    548 store:
    549   store i32 %sub, i32 *%dest2
    550   br label %exit
    551 
    552 exit:
    553   ret i32 %add
    554 }
    555 
    556 ; Make sure that we don't confuse a base register for a destination.
    557 define void @f28(i64 %a, i64 *%dest) {
    558 ; CHECK-LABEL: f28:
    559 ; CHECK: xi 0(%r2), 15
    560 ; CHECK: cgije %r2, 0, .L{{.*}}
    561 ; CHECK: br %r14
    562 entry:
    563   %ptr = inttoptr i64 %a to i8 *
    564   %val = load i8 *%ptr
    565   %xor = xor i8 %val, 15
    566   store i8 %xor, i8 *%ptr
    567   %cmp = icmp eq i64 %a, 0
    568   br i1 %cmp, label %exit, label %store
    569 
    570 store:
    571   store i64 %a, i64 *%dest
    572   br label %exit
    573 
    574 exit:
    575   ret void
    576 }
    577 
    578 ; Test that L gets converted to LT where useful.
    579 define i32 @f29(i64 %base, i64 %index, i32 *%dest) {
    580 ; CHECK-LABEL: f29:
    581 ; CHECK: lt %r2, 0({{%r2,%r3|%r3,%r2}})
    582 ; CHECK-NEXT: jle .L{{.*}}
    583 ; CHECK: br %r14
    584 entry:
    585   %add = add i64 %base, %index
    586   %ptr = inttoptr i64 %add to i32 *
    587   %res = load i32 *%ptr
    588   %cmp = icmp sle i32 %res, 0
    589   br i1 %cmp, label %exit, label %store
    590 
    591 store:
    592   store i32 %res, i32 *%dest
    593   br label %exit
    594 
    595 exit:
    596   ret i32 %res
    597 }
    598 
    599 ; Test that LY gets converted to LT where useful.
    600 define i32 @f30(i64 %base, i64 %index, i32 *%dest) {
    601 ; CHECK-LABEL: f30:
    602 ; CHECK: lt %r2, 100000({{%r2,%r3|%r3,%r2}})
    603 ; CHECK-NEXT: jle .L{{.*}}
    604 ; CHECK: br %r14
    605 entry:
    606   %add1 = add i64 %base, %index
    607   %add2 = add i64 %add1, 100000
    608   %ptr = inttoptr i64 %add2 to i32 *
    609   %res = load i32 *%ptr
    610   %cmp = icmp sle i32 %res, 0
    611   br i1 %cmp, label %exit, label %store
    612 
    613 store:
    614   store i32 %res, i32 *%dest
    615   br label %exit
    616 
    617 exit:
    618   ret i32 %res
    619 }
    620 
    621 ; Test that LG gets converted to LTG where useful.
    622 define i64 @f31(i64 %base, i64 %index, i64 *%dest) {
    623 ; CHECK-LABEL: f31:
    624 ; CHECK: ltg %r2, 0({{%r2,%r3|%r3,%r2}})
    625 ; CHECK-NEXT: jhe .L{{.*}}
    626 ; CHECK: br %r14
    627 entry:
    628   %add = add i64 %base, %index
    629   %ptr = inttoptr i64 %add to i64 *
    630   %res = load i64 *%ptr
    631   %cmp = icmp sge i64 %res, 0
    632   br i1 %cmp, label %exit, label %store
    633 
    634 store:
    635   store i64 %res, i64 *%dest
    636   br label %exit
    637 
    638 exit:
    639   ret i64 %res
    640 }
    641 
    642 ; Test that LGF gets converted to LTGF where useful.
    643 define i64 @f32(i64 %base, i64 %index, i64 *%dest) {
    644 ; CHECK-LABEL: f32:
    645 ; CHECK: ltgf %r2, 0({{%r2,%r3|%r3,%r2}})
    646 ; CHECK-NEXT: jh .L{{.*}}
    647 ; CHECK: br %r14
    648 entry:
    649   %add = add i64 %base, %index
    650   %ptr = inttoptr i64 %add to i32 *
    651   %val = load i32 *%ptr
    652   %res = sext i32 %val to i64
    653   %cmp = icmp sgt i64 %res, 0
    654   br i1 %cmp, label %exit, label %store
    655 
    656 store:
    657   store i64 %res, i64 *%dest
    658   br label %exit
    659 
    660 exit:
    661   ret i64 %res
    662 }
    663 
    664 ; Test that LR gets converted to LTR where useful.
    665 define i32 @f33(i32 %dummy, i32 %val, i32 *%dest) {
    666 ; CHECK-LABEL: f33:
    667 ; CHECK: ltr %r2, %r3
    668 ; CHECK-NEXT: #APP
    669 ; CHECK-NEXT: blah %r2
    670 ; CHECK-NEXT: #NO_APP
    671 ; CHECK-NEXT: jl .L{{.*}}
    672 ; CHECK: br %r14
    673 entry:
    674   call void asm sideeffect "blah $0", "{r2}"(i32 %val)
    675   %cmp = icmp slt i32 %val, 0
    676   br i1 %cmp, label %exit, label %store
    677 
    678 store:
    679   store i32 %val, i32 *%dest
    680   br label %exit
    681 
    682 exit:
    683   ret i32 %val
    684 }
    685 
    686 ; Test that LGR gets converted to LTGR where useful.
    687 define i64 @f34(i64 %dummy, i64 %val, i64 *%dest) {
    688 ; CHECK-LABEL: f34:
    689 ; CHECK: ltgr %r2, %r3
    690 ; CHECK-NEXT: #APP
    691 ; CHECK-NEXT: blah %r2
    692 ; CHECK-NEXT: #NO_APP
    693 ; CHECK-NEXT: jh .L{{.*}}
    694 ; CHECK: br %r14
    695 entry:
    696   call void asm sideeffect "blah $0", "{r2}"(i64 %val)
    697   %cmp = icmp sgt i64 %val, 0
    698   br i1 %cmp, label %exit, label %store
    699 
    700 store:
    701   store i64 %val, i64 *%dest
    702   br label %exit
    703 
    704 exit:
    705   ret i64 %val
    706 }
    707 
    708 ; Test that LGFR gets converted to LTGFR where useful.
    709 define i64 @f35(i64 %dummy, i32 %val, i64 *%dest) {
    710 ; CHECK-LABEL: f35:
    711 ; CHECK: ltgfr %r2, %r3
    712 ; CHECK-NEXT: #APP
    713 ; CHECK-NEXT: blah %r2
    714 ; CHECK-NEXT: #NO_APP
    715 ; CHECK-NEXT: jh .L{{.*}}
    716 ; CHECK: br %r14
    717 entry:
    718   %ext = sext i32 %val to i64
    719   call void asm sideeffect "blah $0", "{r2}"(i64 %ext)
    720   %cmp = icmp sgt i64 %ext, 0
    721   br i1 %cmp, label %exit, label %store
    722 
    723 store:
    724   store i64 %ext, i64 *%dest
    725   br label %exit
    726 
    727 exit:
    728   ret i64 %ext
    729 }
    730 
    731 ; Test a case where it is the source rather than destination of LR that
    732 ; we need.
    733 define i32 @f36(i32 %val, i32 %dummy, i32 *%dest) {
    734 ; CHECK-LABEL: f36:
    735 ; CHECK: ltr %r3, %r2
    736 ; CHECK-NEXT: #APP
    737 ; CHECK-NEXT: blah %r3
    738 ; CHECK-NEXT: #NO_APP
    739 ; CHECK-NEXT: jl .L{{.*}}
    740 ; CHECK: br %r14
    741 entry:
    742   call void asm sideeffect "blah $0", "{r3}"(i32 %val)
    743   %cmp = icmp slt i32 %val, 0
    744   br i1 %cmp, label %exit, label %store
    745 
    746 store:
    747   store i32 %val, i32 *%dest
    748   br label %exit
    749 
    750 exit:
    751   ret i32 %val
    752 }
    753 
    754 ; Test a case where it is the source rather than destination of LGR that
    755 ; we need.
    756 define i64 @f37(i64 %val, i64 %dummy, i64 *%dest) {
    757 ; CHECK-LABEL: f37:
    758 ; CHECK: ltgr %r3, %r2
    759 ; CHECK-NEXT: #APP
    760 ; CHECK-NEXT: blah %r3
    761 ; CHECK-NEXT: #NO_APP
    762 ; CHECK-NEXT: jl .L{{.*}}
    763 ; CHECK: br %r14
    764 entry:
    765   call void asm sideeffect "blah $0", "{r3}"(i64 %val)
    766   %cmp = icmp slt i64 %val, 0
    767   br i1 %cmp, label %exit, label %store
    768 
    769 store:
    770   store i64 %val, i64 *%dest
    771   br label %exit
    772 
    773 exit:
    774   ret i64 %val
    775 }
    776 
    777 ; Test a case where it is the source rather than destination of LGFR that
    778 ; we need.
    779 define i32 @f38(i32 %val, i64 %dummy, i32 *%dest) {
    780 ; CHECK-LABEL: f38:
    781 ; CHECK: ltgfr %r3, %r2
    782 ; CHECK-NEXT: #APP
    783 ; CHECK-NEXT: blah %r3
    784 ; CHECK-NEXT: #NO_APP
    785 ; CHECK-NEXT: jl .L{{.*}}
    786 ; CHECK: br %r14
    787 entry:
    788   %ext = sext i32 %val to i64
    789   call void asm sideeffect "blah $0", "{r3}"(i64 %ext)
    790   %cmp = icmp slt i32 %val, 0
    791   br i1 %cmp, label %exit, label %store
    792 
    793 store:
    794   store i32 %val, i32 *%dest
    795   br label %exit
    796 
    797 exit:
    798   ret i32 %val
    799 }
    800