1 ; Test 64-bit subtraction 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: slgfi %r3, 1 11 ; CHECK-DAG: stg %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 {i64, i1} @llvm.usub.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 SLGFI range. 24 define zeroext i1 @f2(i64 %dummy, i64 %a, i64 *%res) { 25 ; CHECK-LABEL: f2: 26 ; CHECK: slgfi %r3, 4294967295 27 ; CHECK-DAG: stg %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 {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 4294967295) 33 %val = extractvalue {i64, i1} %t, 0 34 %obit = extractvalue {i64, i1} %t, 1 35 store i64 %val, i64 *%res 36 ret i1 %obit 37 } 38 39 ; Check the next value up, which must be loaded into a register first. 40 define zeroext i1 @f3(i64 %dummy, i64 %a, i64 *%res) { 41 ; CHECK-LABEL: f3: 42 ; CHECK: llihl [[REG1:%r[0-9]+]], 1 43 ; CHECK: slgr %r3, [[REG1]] 44 ; CHECK-DAG: stg %r3, 0(%r4) 45 ; CHECK-DAG: ipm [[REG2:%r[0-5]]] 46 ; CHECK-DAG: afi [[REG]], -536870912 47 ; CHECK-DAG: risbg %r2, [[REG2]], 63, 191, 33 48 ; CHECK: br %r14 49 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 4294967296) 50 %val = extractvalue {i64, i1} %t, 0 51 %obit = extractvalue {i64, i1} %t, 1 52 store i64 %val, i64 *%res 53 ret i1 %obit 54 } 55 56 ; Likewise for negative values. 57 define zeroext i1 @f4(i64 %dummy, i64 %a, i64 *%res) { 58 ; CHECK-LABEL: f4: 59 ; CHECK: lghi [[REG1:%r[0-9]+]], -1 60 ; CHECK: slgr %r3, [[REG1]] 61 ; CHECK-DAG: stg %r3, 0(%r4) 62 ; CHECK-DAG: ipm [[REG2:%r[0-5]]] 63 ; CHECK-DAG: afi [[REG]], -536870912 64 ; CHECK-DAG: risbg %r2, [[REG2]], 63, 191, 33 65 ; CHECK: br %r14 66 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 -1) 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 using the overflow result for a branch. 74 define void @f5(i64 %dummy, i64 %a, i64 *%res) { 75 ; CHECK-LABEL: f5: 76 ; CHECK: slgfi %r3, 1 77 ; CHECK: stg %r3, 0(%r4) 78 ; CHECK: jgle foo@PLT 79 ; CHECK: br %r14 80 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1) 81 %val = extractvalue {i64, i1} %t, 0 82 %obit = extractvalue {i64, i1} %t, 1 83 store i64 %val, i64 *%res 84 br i1 %obit, label %call, label %exit 85 86 call: 87 tail call i64 @foo() 88 br label %exit 89 90 exit: 91 ret void 92 } 93 94 ; ... and the same with the inverted direction. 95 define void @f6(i64 %dummy, i64 %a, i64 *%res) { 96 ; CHECK-LABEL: f6: 97 ; CHECK: slgfi %r3, 1 98 ; CHECK: stg %r3, 0(%r4) 99 ; CHECK: jgnle foo@PLT 100 ; CHECK: br %r14 101 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1) 102 %val = extractvalue {i64, i1} %t, 0 103 %obit = extractvalue {i64, i1} %t, 1 104 store i64 %val, i64 *%res 105 br i1 %obit, label %exit, label %call 106 107 call: 108 tail call i64 @foo() 109 br label %exit 110 111 exit: 112 ret void 113 } 114 115 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone 116 117