Home | History | Annotate | Download | only in SystemZ
      1 ; Test 32-bit subtraction in which the second operand is constant.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
      4 
      5 declare i32 @foo()
      6 
      7 ; Check subtraction of 1.
      8 define zeroext i1 @f1(i32 %dummy, i32 %a, i32 *%res) {
      9 ; CHECK-LABEL: f1:
     10 ; CHECK: slfi %r3, 1
     11 ; CHECK-DAG: st %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 {i32, i1} @llvm.usub.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 SLFI range.
     24 define zeroext i1 @f2(i32 %dummy, i32 %a, i32 *%res) {
     25 ; CHECK-LABEL: f2:
     26 ; CHECK: slfi %r3, 4294967295
     27 ; CHECK-DAG: st %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 {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 4294967295)
     33   %val = extractvalue {i32, i1} %t, 0
     34   %obit = extractvalue {i32, i1} %t, 1
     35   store i32 %val, i32 *%res
     36   ret i1 %obit
     37 }
     38 
     39 ; Check that negative values are treated as unsigned
     40 define zeroext i1 @f3(i32 %dummy, i32 %a, i32 *%res) {
     41 ; CHECK-LABEL: f3:
     42 ; CHECK: slfi %r3, 4294967295
     43 ; CHECK-DAG: st %r3, 0(%r4)
     44 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
     45 ; CHECK-DAG: afi [[REG]], -536870912
     46 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
     47 ; CHECK: br %r14
     48   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 -1)
     49   %val = extractvalue {i32, i1} %t, 0
     50   %obit = extractvalue {i32, i1} %t, 1
     51   store i32 %val, i32 *%res
     52   ret i1 %obit
     53 }
     54 
     55 ; Check using the overflow result for a branch.
     56 define void @f4(i32 %dummy, i32 %a, i32 *%res) {
     57 ; CHECK-LABEL: f4:
     58 ; CHECK: slfi %r3, 1
     59 ; CHECK: st %r3, 0(%r4)
     60 ; CHECK: jgle foo@PLT
     61 ; CHECK: br %r14
     62   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 1)
     63   %val = extractvalue {i32, i1} %t, 0
     64   %obit = extractvalue {i32, i1} %t, 1
     65   store i32 %val, i32 *%res
     66   br i1 %obit, label %call, label %exit
     67 
     68 call:
     69   tail call i32 @foo()
     70   br label %exit
     71 
     72 exit:
     73   ret void
     74 }
     75 
     76 ; ... and the same with the inverted direction.
     77 define void @f5(i32 %dummy, i32 %a, i32 *%res) {
     78 ; CHECK-LABEL: f5:
     79 ; CHECK: slfi %r3, 1
     80 ; CHECK: st %r3, 0(%r4)
     81 ; CHECK: jgnle foo@PLT
     82 ; CHECK: br %r14
     83   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 1)
     84   %val = extractvalue {i32, i1} %t, 0
     85   %obit = extractvalue {i32, i1} %t, 1
     86   store i32 %val, i32 *%res
     87   br i1 %obit, label %exit, label %call
     88 
     89 call:
     90   tail call i32 @foo()
     91   br label %exit
     92 
     93 exit:
     94   ret void
     95 }
     96 
     97 declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
     98 
     99