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 | 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: algfi %r3, 1
     11 ; CHECK-DAG: stg %r3, 0(%r4)
     12 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
     13 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 35
     14 ; CHECK: br %r14
     15   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 1)
     16   %val = extractvalue {i64, i1} %t, 0
     17   %obit = extractvalue {i64, i1} %t, 1
     18   store i64 %val, i64 *%res
     19   ret i1 %obit
     20 }
     21 
     22 ; Check the high end of the ALGFI range.
     23 define zeroext i1 @f2(i64 %dummy, i64 %a, i64 *%res) {
     24 ; CHECK-LABEL: f2:
     25 ; CHECK: algfi %r3, 4294967295
     26 ; CHECK-DAG: stg %r3, 0(%r4)
     27 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
     28 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 35
     29 ; CHECK: br %r14
     30   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 4294967295)
     31   %val = extractvalue {i64, i1} %t, 0
     32   %obit = extractvalue {i64, i1} %t, 1
     33   store i64 %val, i64 *%res
     34   ret i1 %obit
     35 }
     36 
     37 ; Check the next value up, which must be loaded into a register first.
     38 define zeroext i1 @f3(i64 %dummy, i64 %a, i64 *%res) {
     39 ; CHECK-LABEL: f3:
     40 ; CHECK: llihl [[REG1:%r[0-9]+]], 1
     41 ; CHECK: algr [[REG1]], %r3
     42 ; CHECK-DAG: stg [[REG1]], 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 4294967296)
     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 ; Likewise for negative values.
     54 define zeroext i1 @f4(i64 %dummy, i64 %a, i64 *%res) {
     55 ; CHECK-LABEL: f4:
     56 ; CHECK: lghi [[REG1:%r[0-9]+]], -1
     57 ; CHECK: algr [[REG1]], %r3
     58 ; CHECK-DAG: stg [[REG1]], 0(%r4)
     59 ; CHECK-DAG: ipm [[REG2:%r[0-5]]]
     60 ; CHECK-DAG: risbg %r2, [[REG2]], 63, 191, 35
     61 ; CHECK: br %r14
     62   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 -1)
     63   %val = extractvalue {i64, i1} %t, 0
     64   %obit = extractvalue {i64, i1} %t, 1
     65   store i64 %val, i64 *%res
     66   ret i1 %obit
     67 }
     68 
     69 ; Check using the overflow result for a branch.
     70 define void @f5(i64 %dummy, i64 %a, i64 *%res) {
     71 ; CHECK-LABEL: f5:
     72 ; CHECK: algfi %r3, 1
     73 ; CHECK: stg %r3, 0(%r4)
     74 ; CHECK: jgnle foo@PLT
     75 ; CHECK: br %r14
     76   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 1)
     77   %val = extractvalue {i64, i1} %t, 0
     78   %obit = extractvalue {i64, i1} %t, 1
     79   store i64 %val, i64 *%res
     80   br i1 %obit, label %call, label %exit
     81 
     82 call:
     83   tail call i64 @foo()
     84   br label %exit
     85 
     86 exit:
     87   ret void
     88 }
     89 
     90 ; ... and the same with the inverted direction.
     91 define void @f6(i64 %dummy, i64 %a, i64 *%res) {
     92 ; CHECK-LABEL: f6:
     93 ; CHECK: algfi %r3, 1
     94 ; CHECK: stg %r3, 0(%r4)
     95 ; CHECK: jgle foo@PLT
     96 ; CHECK: br %r14
     97   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 1)
     98   %val = extractvalue {i64, i1} %t, 0
     99   %obit = extractvalue {i64, i1} %t, 1
    100   store i64 %val, i64 *%res
    101   br i1 %obit, label %exit, label %call
    102 
    103 call:
    104   tail call i64 @foo()
    105   br label %exit
    106 
    107 exit:
    108   ret void
    109 }
    110 
    111 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
    112 
    113