Home | History | Annotate | Download | only in SystemZ
      1 ; Test 64-bit addition in which the second operand is constant and in which
      2 ; three-operand forms are available.
      3 ;
      4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
      5 
      6 declare i64 @foo()
      7 
      8 ; Check additions of 1.
      9 define zeroext i1 @f1(i64 %dummy, i64 %a, i64 *%res) {
     10 ; CHECK-LABEL: f1:
     11 ; CHECK: alghsik [[REG1:%r[0-5]]], %r3, 1
     12 ; CHECK-DAG: stg [[REG1]], 0(%r4)
     13 ; CHECK-DAG: ipm [[REG2:%r[0-5]]]
     14 ; CHECK-DAG: risbg %r2, [[REG2]], 63, 191, 35
     15 ; CHECK: br %r14
     16   %t = call {i64, i1} @llvm.uadd.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 ALGHSIK range.
     24 define zeroext i1 @f2(i64 %dummy, i64 %a, i64 *%res) {
     25 ; CHECK-LABEL: f2:
     26 ; CHECK: alghsik [[REG1:%r[0-5]]], %r3, 32767
     27 ; CHECK-DAG: stg [[REG1]], 0(%r4)
     28 ; CHECK-DAG: ipm [[REG2:%r[0-5]]]
     29 ; CHECK-DAG: risbg %r2, [[REG2]], 63, 191, 35
     30 ; CHECK: br %r14
     31   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 32767)
     32   %val = extractvalue {i64, i1} %t, 0
     33   %obit = extractvalue {i64, i1} %t, 1
     34   store i64 %val, i64 *%res
     35   ret i1 %obit
     36 }
     37 
     38 ; Check the next value up, which must use ALGFI instead.
     39 define zeroext i1 @f3(i64 %dummy, i64 %a, i64 *%res) {
     40 ; CHECK-LABEL: f3:
     41 ; CHECK: algfi %r3, 32768
     42 ; CHECK-DAG: stg %r3, 0(%r4)
     43 ; CHECK-DAG: ipm [[REG2:%r[0-5]]]
     44 ; CHECK-DAG: risbg %r2, [[REG2]], 63, 191, 35
     45 ; CHECK: br %r14
     46   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 32768)
     47   %val = extractvalue {i64, i1} %t, 0
     48   %obit = extractvalue {i64, i1} %t, 1
     49   store i64 %val, i64 *%res
     50   ret i1 %obit
     51 }
     52 
     53 ; Check the high end of the negative ALGHSIK range.
     54 define zeroext i1 @f4(i64 %dummy, i64 %a, i64 *%res) {
     55 ; CHECK-LABEL: f4:
     56 ; CHECK: alghsik [[REG1:%r[0-5]]], %r3, -1
     57 ; CHECK-DAG: stg [[REG1]], 0(%r4)
     58 ; CHECK-DAG: ipm [[REG2:%r[0-5]]]
     59 ; CHECK-DAG: risbg %r2, [[REG2]], 63, 191, 35
     60 ; CHECK: br %r14
     61   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 -1)
     62   %val = extractvalue {i64, i1} %t, 0
     63   %obit = extractvalue {i64, i1} %t, 1
     64   store i64 %val, i64 *%res
     65   ret i1 %obit
     66 }
     67 
     68 ; Check the low end of the ALGHSIK range.
     69 define zeroext i1 @f5(i64 %dummy, i64 %a, i64 *%res) {
     70 ; CHECK-LABEL: f5:
     71 ; CHECK: alghsik [[REG1:%r[0-5]]], %r3, -32768
     72 ; CHECK-DAG: stg [[REG1]], 0(%r4)
     73 ; CHECK-DAG: ipm [[REG2:%r[0-5]]]
     74 ; CHECK-DAG: risbg %r2, [[REG2]], 63, 191, 35
     75 ; CHECK: br %r14
     76   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 -32768)
     77   %val = extractvalue {i64, i1} %t, 0
     78   %obit = extractvalue {i64, i1} %t, 1
     79   store i64 %val, i64 *%res
     80   ret i1 %obit
     81 }
     82 
     83 ; Test the next value down, which cannot use either ALGHSIK or ALGFI.
     84 define zeroext i1 @f6(i64 %dummy, i64 %a, i64 *%res) {
     85 ; CHECK-LABEL: f6:
     86 ; CHECK-NOT: alghsik
     87 ; CHECK-NOT: algfi
     88 ; CHECK: br %r14
     89   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 -32769)
     90   %val = extractvalue {i64, i1} %t, 0
     91   %obit = extractvalue {i64, i1} %t, 1
     92   store i64 %val, i64 *%res
     93   ret i1 %obit
     94 }
     95 
     96 ; Check using the overflow result for a branch.
     97 define void @f7(i64 %dummy, i64 %a, i64 *%res) {
     98 ; CHECK-LABEL: f7:
     99 ; CHECK: alghsik [[REG1:%r[0-5]]], %r3, 1
    100 ; CHECK-DAG: stg [[REG1]], 0(%r4)
    101 ; CHECK: jgnle foo@PLT
    102 ; CHECK: br %r14
    103   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 1)
    104   %val = extractvalue {i64, i1} %t, 0
    105   %obit = extractvalue {i64, i1} %t, 1
    106   store i64 %val, i64 *%res
    107   br i1 %obit, label %call, label %exit
    108 
    109 call:
    110   tail call i64 @foo()
    111   br label %exit
    112 
    113 exit:
    114   ret void
    115 }
    116 
    117 ; ... and the same with the inverted direction.
    118 define void @f8(i64 %dummy, i64 %a, i64 *%res) {
    119 ; CHECK-LABEL: f8:
    120 ; CHECK: alghsik [[REG1:%r[0-5]]], %r3, 1
    121 ; CHECK-DAG: stg [[REG1]], 0(%r4)
    122 ; CHECK: jgle foo@PLT
    123 ; CHECK: br %r14
    124   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 1)
    125   %val = extractvalue {i64, i1} %t, 0
    126   %obit = extractvalue {i64, i1} %t, 1
    127   store i64 %val, i64 *%res
    128   br i1 %obit, label %exit, label %call
    129 
    130 call:
    131   tail call i64 @foo()
    132   br label %exit
    133 
    134 exit:
    135   ret void
    136 }
    137 
    138 
    139 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
    140 
    141