xref: /llvm-project/llvm/test/CodeGen/SystemZ/int-usub-05.ll (revision 872276de4b8c5f13f106b79c53a27e4a6ff8ce35)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
2; Test 64-bit subtraction in which the second operand is constant.
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5
6declare i64 @foo()
7
8; Check addition of 1.
9define zeroext i1 @f1(i64 %dummy, i64 %a, ptr %res) {
10; CHECK-LABEL: f1:
11; CHECK:       # %bb.0:
12; CHECK-NEXT:    slgfi %r3, 1
13; CHECK-NEXT:    ipm %r0
14; CHECK-NEXT:    afi %r0, -536870912
15; CHECK-NEXT:    risbg %r2, %r0, 63, 191, 33
16; CHECK-NEXT:    stg %r3, 0(%r4)
17; CHECK-NEXT:    br %r14
18  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1)
19  %val = extractvalue {i64, i1} %t, 0
20  %obit = extractvalue {i64, i1} %t, 1
21  store i64 %val, ptr %res
22  ret i1 %obit
23}
24
25; Check the high end of the SLGFI range.
26define zeroext i1 @f2(i64 %dummy, i64 %a, ptr %res) {
27; CHECK-LABEL: f2:
28; CHECK:       # %bb.0:
29; CHECK-NEXT:    slgfi %r3, 4294967295
30; CHECK-NEXT:    ipm %r0
31; CHECK-NEXT:    afi %r0, -536870912
32; CHECK-NEXT:    risbg %r2, %r0, 63, 191, 33
33; CHECK-NEXT:    stg %r3, 0(%r4)
34; CHECK-NEXT:    br %r14
35  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 4294967295)
36  %val = extractvalue {i64, i1} %t, 0
37  %obit = extractvalue {i64, i1} %t, 1
38  store i64 %val, ptr %res
39  ret i1 %obit
40}
41
42; Check the next value up, which must be loaded into a register first.
43define zeroext i1 @f3(i64 %dummy, i64 %a, ptr %res) {
44; CHECK-LABEL: f3:
45; CHECK:       # %bb.0:
46; CHECK-NEXT:    llihl %r0, 1
47; CHECK-NEXT:    slgr %r3, %r0
48; CHECK-NEXT:    ipm %r0
49; CHECK-NEXT:    afi %r0, -536870912
50; CHECK-NEXT:    risbg %r2, %r0, 63, 191, 33
51; CHECK-NEXT:    stg %r3, 0(%r4)
52; CHECK-NEXT:    br %r14
53  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 4294967296)
54  %val = extractvalue {i64, i1} %t, 0
55  %obit = extractvalue {i64, i1} %t, 1
56  store i64 %val, ptr %res
57  ret i1 %obit
58}
59
60; Likewise for negative values.
61define zeroext i1 @f4(i64 %dummy, i64 %a, ptr %res) {
62; CHECK-LABEL: f4:
63; CHECK:       # %bb.0:
64; CHECK-NEXT:    lghi %r0, -1
65; CHECK-NEXT:    slgr %r3, %r0
66; CHECK-NEXT:    ipm %r0
67; CHECK-NEXT:    afi %r0, -536870912
68; CHECK-NEXT:    risbg %r2, %r0, 63, 191, 33
69; CHECK-NEXT:    stg %r3, 0(%r4)
70; CHECK-NEXT:    br %r14
71  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 -1)
72  %val = extractvalue {i64, i1} %t, 0
73  %obit = extractvalue {i64, i1} %t, 1
74  store i64 %val, ptr %res
75  ret i1 %obit
76}
77
78; Check using the overflow result for a branch.
79define void @f5(i64 %dummy, i64 %a, ptr %res) {
80; CHECK-LABEL: f5:
81; CHECK:       # %bb.0:
82; CHECK-NEXT:    slgfi %r3, 1
83; CHECK-NEXT:    stg %r3, 0(%r4)
84; CHECK-NEXT:    jgle foo@PLT
85; CHECK-NEXT:  .LBB4_1: # %exit
86; CHECK-NEXT:    br %r14
87  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1)
88  %val = extractvalue {i64, i1} %t, 0
89  %obit = extractvalue {i64, i1} %t, 1
90  store i64 %val, ptr %res
91  br i1 %obit, label %call, label %exit
92
93call:
94  tail call i64 @foo()
95  br label %exit
96
97exit:
98  ret void
99}
100
101; ... and the same with the inverted direction.
102define void @f6(i64 %dummy, i64 %a, ptr %res) {
103; CHECK-LABEL: f6:
104; CHECK:       # %bb.0:
105; CHECK-NEXT:    slgfi %r3, 1
106; CHECK-NEXT:    stg %r3, 0(%r4)
107; CHECK-NEXT:    jgnle foo@PLT
108; CHECK-NEXT:  .LBB5_1: # %exit
109; CHECK-NEXT:    br %r14
110  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1)
111  %val = extractvalue {i64, i1} %t, 0
112  %obit = extractvalue {i64, i1} %t, 1
113  store i64 %val, ptr %res
114  br i1 %obit, label %exit, label %call
115
116call:
117  tail call i64 @foo()
118  br label %exit
119
120exit:
121  ret void
122}
123
124declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
125
126