Home | History | Annotate | Download | only in SystemZ
      1 ; Test 64-bit addition in which the second operand is constant.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
      4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
      5 
      6 declare i32 @foo()
      7 
      8 ; Check additions of 1.
      9 define zeroext i1 @f1(i64 %dummy, i64 %a, i64 *%res) {
     10 ; CHECK-LABEL: f1:
     11 ; CHECK: aghi %r3, 1
     12 ; CHECK-DAG: stg %r3, 0(%r4)
     13 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
     14 ; CHECK-DAG: afi [[REG]], 1342177280
     15 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
     16 ; CHECK: br %r14
     17   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 1)
     18   %val = extractvalue {i64, i1} %t, 0
     19   %obit = extractvalue {i64, i1} %t, 1
     20   store i64 %val, i64 *%res
     21   ret i1 %obit
     22 
     23 }
     24 
     25 ; Check the high end of the AGHI range.
     26 define zeroext i1 @f2(i64 %dummy, i64 %a, i64 *%res) {
     27 ; CHECK-LABEL: f2:
     28 ; CHECK: aghi %r3, 32767
     29 ; CHECK-DAG: stg %r3, 0(%r4)
     30 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
     31 ; CHECK-DAG: afi [[REG]], 1342177280
     32 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
     33 ; CHECK: br %r14
     34   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 32767)
     35   %val = extractvalue {i64, i1} %t, 0
     36   %obit = extractvalue {i64, i1} %t, 1
     37   store i64 %val, i64 *%res
     38   ret i1 %obit
     39 }
     40 
     41 ; Check the next value up, which must use AGFI instead.
     42 define zeroext i1 @f3(i64 %dummy, i64 %a, i64 *%res) {
     43 ; CHECK-LABEL: f3:
     44 ; CHECK: agfi %r3, 32768
     45 ; CHECK-DAG: stg %r3, 0(%r4)
     46 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
     47 ; CHECK-DAG: afi [[REG]], 1342177280
     48 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
     49 ; CHECK: br %r14
     50   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 32768)
     51   %val = extractvalue {i64, i1} %t, 0
     52   %obit = extractvalue {i64, i1} %t, 1
     53   store i64 %val, i64 *%res
     54   ret i1 %obit
     55 }
     56 
     57 ; Check the high end of the AGFI range.
     58 define zeroext i1 @f4(i64 %dummy, i64 %a, i64 *%res) {
     59 ; CHECK-LABEL: f4:
     60 ; CHECK: agfi %r3, 2147483647
     61 ; CHECK-DAG: stg %r3, 0(%r4)
     62 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
     63 ; CHECK-DAG: afi [[REG]], 1342177280
     64 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
     65 ; CHECK: br %r14
     66   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 2147483647)
     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 the next value up, which must be loaded into a register first.
     74 define zeroext i1 @f5(i64 %dummy, i64 %a, i64 *%res) {
     75 ; CHECK-LABEL: f5:
     76 ; CHECK: llilh [[REG1:%r[0-9]+]], 32768
     77 ; CHECK: agr [[REG1]], %r3
     78 ; CHECK-DAG: stg [[REG1]], 0(%r4)
     79 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
     80 ; CHECK-DAG: afi [[REG]], 1342177280
     81 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
     82 ; CHECK: br %r14
     83   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 2147483648)
     84   %val = extractvalue {i64, i1} %t, 0
     85   %obit = extractvalue {i64, i1} %t, 1
     86   store i64 %val, i64 *%res
     87   ret i1 %obit
     88 }
     89 
     90 ; Check the high end of the negative AGHI range.
     91 define zeroext i1 @f6(i64 %dummy, i64 %a, i64 *%res) {
     92 ; CHECK-LABEL: f6:
     93 ; CHECK: aghi %r3, -1
     94 ; CHECK-DAG: stg %r3, 0(%r4)
     95 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
     96 ; CHECK-DAG: afi [[REG]], 1342177280
     97 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
     98 ; CHECK: br %r14
     99   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 -1)
    100   %val = extractvalue {i64, i1} %t, 0
    101   %obit = extractvalue {i64, i1} %t, 1
    102   store i64 %val, i64 *%res
    103   ret i1 %obit
    104 }
    105 
    106 ; Check the low end of the AGHI range.
    107 define zeroext i1 @f7(i64 %dummy, i64 %a, i64 *%res) {
    108 ; CHECK-LABEL: f7:
    109 ; CHECK: aghi %r3, -32768
    110 ; CHECK-DAG: stg %r3, 0(%r4)
    111 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
    112 ; CHECK-DAG: afi [[REG]], 1342177280
    113 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
    114 ; CHECK: br %r14
    115   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 -32768)
    116   %val = extractvalue {i64, i1} %t, 0
    117   %obit = extractvalue {i64, i1} %t, 1
    118   store i64 %val, i64 *%res
    119   ret i1 %obit
    120 }
    121 
    122 ; Check the next value down, which must use AGFI instead.
    123 define zeroext i1 @f8(i64 %dummy, i64 %a, i64 *%res) {
    124 ; CHECK-LABEL: f8:
    125 ; CHECK: agfi %r3, -32769
    126 ; CHECK-DAG: stg %r3, 0(%r4)
    127 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
    128 ; CHECK-DAG: afi [[REG]], 1342177280
    129 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
    130 ; CHECK: br %r14
    131   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 -32769)
    132   %val = extractvalue {i64, i1} %t, 0
    133   %obit = extractvalue {i64, i1} %t, 1
    134   store i64 %val, i64 *%res
    135   ret i1 %obit
    136 }
    137 
    138 ; Check the low end of the AGFI range.
    139 define zeroext i1 @f9(i64 %dummy, i64 %a, i64 *%res) {
    140 ; CHECK-LABEL: f9:
    141 ; CHECK: agfi %r3, -2147483648
    142 ; CHECK-DAG: stg %r3, 0(%r4)
    143 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
    144 ; CHECK-DAG: afi [[REG]], 1342177280
    145 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
    146 ; CHECK: br %r14
    147   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 -2147483648)
    148   %val = extractvalue {i64, i1} %t, 0
    149   %obit = extractvalue {i64, i1} %t, 1
    150   store i64 %val, i64 *%res
    151   ret i1 %obit
    152 }
    153 
    154 ; Check the next value down, which must use register addition instead.
    155 define zeroext i1 @f10(i64 %dummy, i64 %a, i64 *%res) {
    156 ; CHECK-LABEL: f10:
    157 ; CHECK: llihf [[REG1:%r[0-9]+]], 4294967295
    158 ; CHECK: agr [[REG1]], %r3
    159 ; CHECK-DAG: stg [[REG1]], 0(%r4)
    160 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
    161 ; CHECK-DAG: afi [[REG]], 1342177280
    162 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
    163 ; CHECK: br %r14
    164   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 -2147483649)
    165   %val = extractvalue {i64, i1} %t, 0
    166   %obit = extractvalue {i64, i1} %t, 1
    167   store i64 %val, i64 *%res
    168   ret i1 %obit
    169 }
    170 
    171 ; Check using the overflow result for a branch.
    172 define void @f11(i64 %dummy, i64 %a, i64 *%res) {
    173 ; CHECK-LABEL: f11:
    174 ; CHECK: aghi %r3, 1
    175 ; CHECK: stg %r3, 0(%r4)
    176 ; CHECK: {{jgo foo@PLT|bnor %r14}}
    177 ; CHECK: {{br %r14|jg foo@PLT}}
    178   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 1)
    179   %val = extractvalue {i64, i1} %t, 0
    180   %obit = extractvalue {i64, i1} %t, 1
    181   store i64 %val, i64 *%res
    182   br i1 %obit, label %call, label %exit
    183 
    184 call:
    185   tail call i32 @foo()
    186   br label %exit
    187 
    188 exit:
    189   ret void
    190 }
    191 
    192 ; ... and the same with the inverted direction.
    193 define void @f12(i64 %dummy, i64 %a, i64 *%res) {
    194 ; CHECK-LABEL: f12:
    195 ; CHECK: aghi %r3, 1
    196 ; CHECK: stg %r3, 0(%r4)
    197 ; CHECK: {{jgno foo@PLT|bor %r14}}
    198 ; CHECK: {{br %r14|jg foo@PLT}}
    199   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 1)
    200   %val = extractvalue {i64, i1} %t, 0
    201   %obit = extractvalue {i64, i1} %t, 1
    202   store i64 %val, i64 *%res
    203   br i1 %obit, label %exit, label %call
    204 
    205 call:
    206   tail call i32 @foo()
    207   br label %exit
    208 
    209 exit:
    210   ret void
    211 }
    212 
    213 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
    214 
    215