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