xref: /llvm-project/llvm/test/CodeGen/SystemZ/int-usub-09.ll (revision 872276de4b8c5f13f106b79c53a27e4a6ff8ce35)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
2; Test 64-bit addition in which the second operand is constant and in which
3; three-operand forms are available.
4;
5; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
6
7declare i64 @foo()
8
9; Check subtraction of 1.
10define zeroext i1 @f1(i64 %dummy, i64 %a, ptr %res) {
11; CHECK-LABEL: f1:
12; CHECK:       # %bb.0:
13; CHECK-NEXT:    alghsik %r0, %r3, -1
14; CHECK-NEXT:    stg %r0, 0(%r4)
15; CHECK-NEXT:    ipm %r1
16; CHECK-NEXT:    afi %r1, -536870912
17; CHECK-NEXT:    risbg %r2, %r1, 63, 191, 33
18; CHECK-NEXT:    br %r14
19  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1)
20  %val = extractvalue {i64, i1} %t, 0
21  %obit = extractvalue {i64, i1} %t, 1
22  store i64 %val, ptr %res
23  ret i1 %obit
24}
25
26; Check the high end of the ALGHSIK range.
27define zeroext i1 @f2(i64 %dummy, i64 %a, ptr %res) {
28; CHECK-LABEL: f2:
29; CHECK:       # %bb.0:
30; CHECK-NEXT:    alghsik %r0, %r3, -32768
31; CHECK-NEXT:    stg %r0, 0(%r4)
32; CHECK-NEXT:    ipm %r1
33; CHECK-NEXT:    afi %r1, -536870912
34; CHECK-NEXT:    risbg %r2, %r1, 63, 191, 33
35; CHECK-NEXT:    br %r14
36  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 32768)
37  %val = extractvalue {i64, i1} %t, 0
38  %obit = extractvalue {i64, i1} %t, 1
39  store i64 %val, ptr %res
40  ret i1 %obit
41}
42
43; Check the next value up, which must use SLGFI instead.
44define zeroext i1 @f3(i64 %dummy, i64 %a, ptr %res) {
45; CHECK-LABEL: f3:
46; CHECK:       # %bb.0:
47; CHECK-NEXT:    slgfi %r3, 32769
48; CHECK-NEXT:    stg %r3, 0(%r4)
49; CHECK-NEXT:    ipm %r0
50; CHECK-NEXT:    afi %r0, -536870912
51; CHECK-NEXT:    risbg %r2, %r0, 63, 191, 33
52; CHECK-NEXT:    br %r14
53  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 32769)
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; Check the high end of the negative ALGHSIK range.
61define zeroext i1 @f4(i64 %dummy, i64 %a, ptr %res) {
62; CHECK-LABEL: f4:
63; CHECK:       # %bb.0:
64; CHECK-NEXT:    alghsik %r0, %r3, 1
65; CHECK-NEXT:    stg %r0, 0(%r4)
66; CHECK-NEXT:    ipm %r1
67; CHECK-NEXT:    afi %r1, -536870912
68; CHECK-NEXT:    risbg %r2, %r1, 63, 191, 33
69; CHECK-NEXT:    br %r14
70  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 -1)
71  %val = extractvalue {i64, i1} %t, 0
72  %obit = extractvalue {i64, i1} %t, 1
73  store i64 %val, ptr %res
74  ret i1 %obit
75}
76
77; Check the low end of the ALGHSIK range.
78define zeroext i1 @f5(i64 %dummy, i64 %a, ptr %res) {
79; CHECK-LABEL: f5:
80; CHECK:       # %bb.0:
81; CHECK-NEXT:    alghsik %r0, %r3, 32767
82; CHECK-NEXT:    stg %r0, 0(%r4)
83; CHECK-NEXT:    ipm %r1
84; CHECK-NEXT:    afi %r1, -536870912
85; CHECK-NEXT:    risbg %r2, %r1, 63, 191, 33
86; CHECK-NEXT:    br %r14
87  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 -32767)
88  %val = extractvalue {i64, i1} %t, 0
89  %obit = extractvalue {i64, i1} %t, 1
90  store i64 %val, ptr %res
91  ret i1 %obit
92}
93
94; Test the next value down, which cannot use either ALGHSIK or SLGFI.
95define zeroext i1 @f6(i64 %dummy, i64 %a, ptr %res) {
96; CHECK-LABEL: f6:
97; CHECK:       # %bb.0:
98; CHECK-NEXT:    lghi %r0, -32768
99; CHECK-NEXT:    slgr %r3, %r0
100; CHECK-NEXT:    ipm %r0
101; CHECK-NEXT:    afi %r0, -536870912
102; CHECK-NEXT:    risbg %r2, %r0, 63, 191, 33
103; CHECK-NEXT:    stg %r3, 0(%r4)
104; CHECK-NEXT:    br %r14
105  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 -32768)
106  %val = extractvalue {i64, i1} %t, 0
107  %obit = extractvalue {i64, i1} %t, 1
108  store i64 %val, ptr %res
109  ret i1 %obit
110}
111
112; Check using the overflow result for a branch.
113define void @f7(i64 %dummy, i64 %a, ptr %res) {
114; CHECK-LABEL: f7:
115; CHECK:       # %bb.0:
116; CHECK-NEXT:    alghsik %r0, %r3, -1
117; CHECK-NEXT:    stg %r0, 0(%r4)
118; CHECK-NEXT:    jgle foo@PLT
119; CHECK-NEXT:  .LBB6_1: # %exit
120; CHECK-NEXT:    br %r14
121  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1)
122  %val = extractvalue {i64, i1} %t, 0
123  %obit = extractvalue {i64, i1} %t, 1
124  store i64 %val, ptr %res
125  br i1 %obit, label %call, label %exit
126
127call:
128  tail call i64 @foo()
129  br label %exit
130
131exit:
132  ret void
133}
134
135; ... and the same with the inverted direction.
136define void @f8(i64 %dummy, i64 %a, ptr %res) {
137; CHECK-LABEL: f8:
138; CHECK:       # %bb.0:
139; CHECK-NEXT:    alghsik %r0, %r3, -1
140; CHECK-NEXT:    stg %r0, 0(%r4)
141; CHECK-NEXT:    jgnle foo@PLT
142; CHECK-NEXT:  .LBB7_1: # %exit
143; CHECK-NEXT:    br %r14
144  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1)
145  %val = extractvalue {i64, i1} %t, 0
146  %obit = extractvalue {i64, i1} %t, 1
147  store i64 %val, ptr %res
148  br i1 %obit, label %exit, label %call
149
150call:
151  tail call i64 @foo()
152  br label %exit
153
154exit:
155  ret void
156}
157
158
159declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
160
161