Home | History | Annotate | Download | only in SystemZ
      1 ; Test 64-bit subtraction in which the second operand is constant.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
      4 
      5 declare i64 @foo()
      6 
      7 ; Check addition of 1.
      8 define zeroext i1 @f1(i64 %dummy, i64 %a, i64 *%res) {
      9 ; CHECK-LABEL: f1:
     10 ; CHECK: slgfi %r3, 1
     11 ; CHECK-DAG: stg %r3, 0(%r4)
     12 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
     13 ; CHECK-DAG: afi [[REG]], -536870912
     14 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
     15 ; CHECK: br %r14
     16   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1)
     17   %val = extractvalue {i64, i1} %t, 0
     18   %obit = extractvalue {i64, i1} %t, 1
     19   store i64 %val, i64 *%res
     20   ret i1 %obit
     21 }
     22 
     23 ; Check the high end of the SLGFI range.
     24 define zeroext i1 @f2(i64 %dummy, i64 %a, i64 *%res) {
     25 ; CHECK-LABEL: f2:
     26 ; CHECK: slgfi %r3, 4294967295
     27 ; CHECK-DAG: stg %r3, 0(%r4)
     28 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
     29 ; CHECK-DAG: afi [[REG]], -536870912
     30 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
     31 ; CHECK: br %r14
     32   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 4294967295)
     33   %val = extractvalue {i64, i1} %t, 0
     34   %obit = extractvalue {i64, i1} %t, 1
     35   store i64 %val, i64 *%res
     36   ret i1 %obit
     37 }
     38 
     39 ; Check the next value up, which must be loaded into a register first.
     40 define zeroext i1 @f3(i64 %dummy, i64 %a, i64 *%res) {
     41 ; CHECK-LABEL: f3:
     42 ; CHECK: llihl [[REG1:%r[0-9]+]], 1
     43 ; CHECK: slgr %r3, [[REG1]]
     44 ; CHECK-DAG: stg %r3, 0(%r4)
     45 ; CHECK-DAG: ipm [[REG2:%r[0-5]]]
     46 ; CHECK-DAG: afi [[REG]], -536870912
     47 ; CHECK-DAG: risbg %r2, [[REG2]], 63, 191, 33
     48 ; CHECK: br %r14
     49   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 4294967296)
     50   %val = extractvalue {i64, i1} %t, 0
     51   %obit = extractvalue {i64, i1} %t, 1
     52   store i64 %val, i64 *%res
     53   ret i1 %obit
     54 }
     55 
     56 ; Likewise for negative values.
     57 define zeroext i1 @f4(i64 %dummy, i64 %a, i64 *%res) {
     58 ; CHECK-LABEL: f4:
     59 ; CHECK: lghi [[REG1:%r[0-9]+]], -1
     60 ; CHECK: slgr %r3, [[REG1]]
     61 ; CHECK-DAG: stg %r3, 0(%r4)
     62 ; CHECK-DAG: ipm [[REG2:%r[0-5]]]
     63 ; CHECK-DAG: afi [[REG]], -536870912
     64 ; CHECK-DAG: risbg %r2, [[REG2]], 63, 191, 33
     65 ; CHECK: br %r14
     66   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 -1)
     67   %val = extractvalue {i64, i1} %t, 0
     68   %obit = extractvalue {i64, i1} %t, 1
     69   store i64 %val, i64 *%res
     70   ret i1 %obit
     71 }
     72 
     73 ; Check using the overflow result for a branch.
     74 define void @f5(i64 %dummy, i64 %a, i64 *%res) {
     75 ; CHECK-LABEL: f5:
     76 ; CHECK: slgfi %r3, 1
     77 ; CHECK: stg %r3, 0(%r4)
     78 ; CHECK: jgle foo@PLT
     79 ; CHECK: br %r14
     80   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1)
     81   %val = extractvalue {i64, i1} %t, 0
     82   %obit = extractvalue {i64, i1} %t, 1
     83   store i64 %val, i64 *%res
     84   br i1 %obit, label %call, label %exit
     85 
     86 call:
     87   tail call i64 @foo()
     88   br label %exit
     89 
     90 exit:
     91   ret void
     92 }
     93 
     94 ; ... and the same with the inverted direction.
     95 define void @f6(i64 %dummy, i64 %a, i64 *%res) {
     96 ; CHECK-LABEL: f6:
     97 ; CHECK: slgfi %r3, 1
     98 ; CHECK: stg %r3, 0(%r4)
     99 ; CHECK: jgnle foo@PLT
    100 ; CHECK: br %r14
    101   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1)
    102   %val = extractvalue {i64, i1} %t, 0
    103   %obit = extractvalue {i64, i1} %t, 1
    104   store i64 %val, i64 *%res
    105   br i1 %obit, label %exit, label %call
    106 
    107 call:
    108   tail call i64 @foo()
    109   br label %exit
    110 
    111 exit:
    112   ret void
    113 }
    114 
    115 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
    116 
    117