Home | History | Annotate | Download | only in SystemZ
      1 ; Test 32-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 i32 @foo()
      7 
      8 ; Check addition of 1.
      9 define zeroext i1 @f1(i32 %dummy, i32 %a, i32 *%res) {
     10 ; CHECK-LABEL: f1:
     11 ; CHECK: alhsik [[REG1:%r[0-5]]], %r3, 1
     12 ; CHECK-DAG: st [[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 {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)
     17   %val = extractvalue {i32, i1} %t, 0
     18   %obit = extractvalue {i32, i1} %t, 1
     19   store i32 %val, i32 *%res
     20   ret i1 %obit
     21 }
     22 
     23 ; Check the high end of the ALHSIK range.
     24 define zeroext i1 @f2(i32 %dummy, i32 %a, i32 *%res) {
     25 ; CHECK-LABEL: f2:
     26 ; CHECK: alhsik [[REG1:%r[0-5]]], %r3, 32767
     27 ; CHECK-DAG: st [[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 {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 32767)
     32   %val = extractvalue {i32, i1} %t, 0
     33   %obit = extractvalue {i32, i1} %t, 1
     34   store i32 %val, i32 *%res
     35   ret i1 %obit
     36 }
     37 
     38 ; Check the next value up, which must use ALFI instead.
     39 define zeroext i1 @f3(i32 %dummy, i32 %a, i32 *%res) {
     40 ; CHECK-LABEL: f3:
     41 ; CHECK: alfi %r3, 32768
     42 ; CHECK-DAG: st %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 {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 32768)
     47   %val = extractvalue {i32, i1} %t, 0
     48   %obit = extractvalue {i32, i1} %t, 1
     49   store i32 %val, i32 *%res
     50   ret i1 %obit
     51 }
     52 
     53 ; Check the high end of the negative ALHSIK range.
     54 define zeroext i1 @f4(i32 %dummy, i32 %a, i32 *%res) {
     55 ; CHECK-LABEL: f4:
     56 ; CHECK: alhsik [[REG1:%r[0-5]]], %r3, -1
     57 ; CHECK-DAG: st [[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 {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 -1)
     62   %val = extractvalue {i32, i1} %t, 0
     63   %obit = extractvalue {i32, i1} %t, 1
     64   store i32 %val, i32 *%res
     65   ret i1 %obit
     66 }
     67 
     68 ; Check the low end of the ALHSIK range.
     69 define zeroext i1 @f5(i32 %dummy, i32 %a, i32 *%res) {
     70 ; CHECK-LABEL: f5:
     71 ; CHECK: alhsik [[REG1:%r[0-5]]], %r3, -32768
     72 ; CHECK-DAG: st [[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 {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 -32768)
     77   %val = extractvalue {i32, i1} %t, 0
     78   %obit = extractvalue {i32, i1} %t, 1
     79   store i32 %val, i32 *%res
     80   ret i1 %obit
     81 }
     82 
     83 ; Check the next value down, which must use ALFI instead.
     84 define zeroext i1 @f6(i32 %dummy, i32 %a, i32 *%res) {
     85 ; CHECK-LABEL: f6:
     86 ; CHECK: alfi %r3, 4294934527
     87 ; CHECK-DAG: st %r3, 0(%r4)
     88 ; CHECK-DAG: ipm [[REG2:%r[0-5]]]
     89 ; CHECK-DAG: risbg %r2, [[REG2]], 63, 191, 35
     90 ; CHECK: br %r14
     91   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 -32769)
     92   %val = extractvalue {i32, i1} %t, 0
     93   %obit = extractvalue {i32, i1} %t, 1
     94   store i32 %val, i32 *%res
     95   ret i1 %obit
     96 }
     97 
     98 ; Check using the overflow result for a branch.
     99 define void @f7(i32 %dummy, i32 %a, i32 *%res) {
    100 ; CHECK-LABEL: f7:
    101 ; CHECK: alhsik [[REG1:%r[0-5]]], %r3, 1
    102 ; CHECK-DAG: st [[REG1]], 0(%r4)
    103 ; CHECK: jgnle foo@PLT
    104 ; CHECK: br %r14
    105   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)
    106   %val = extractvalue {i32, i1} %t, 0
    107   %obit = extractvalue {i32, i1} %t, 1
    108   store i32 %val, i32 *%res
    109   br i1 %obit, label %call, label %exit
    110 
    111 call:
    112   tail call i32 @foo()
    113   br label %exit
    114 
    115 exit:
    116   ret void
    117 }
    118 
    119 ; ... and the same with the inverted direction.
    120 define void @f8(i32 %dummy, i32 %a, i32 *%res) {
    121 ; CHECK-LABEL: f8:
    122 ; CHECK: alhsik [[REG1:%r[0-5]]], %r3, 1
    123 ; CHECK-DAG: st [[REG1]], 0(%r4)
    124 ; CHECK: jgle foo@PLT
    125 ; CHECK: br %r14
    126   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)
    127   %val = extractvalue {i32, i1} %t, 0
    128   %obit = extractvalue {i32, i1} %t, 1
    129   store i32 %val, i32 *%res
    130   br i1 %obit, label %exit, label %call
    131 
    132 call:
    133   tail call i32 @foo()
    134   br label %exit
    135 
    136 exit:
    137   ret void
    138 }
    139 
    140 
    141 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
    142 
    143