[lldb] Make sure Blocks always have a parent (#117683)
[llvm-project.git] / llvm / test / CodeGen / SystemZ / int-ssub-05.ll
blob9f2233819e7f980e0656a0109a7506406d371228
1 ; Test subtractions between an i64 and a sign-extended i16 on z14.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
5 declare i64 @foo()
7 ; Check SGH with no displacement.
8 define zeroext i1 @f1(i64 %dummy, i64 %a, ptr %src, ptr %res) {
9 ; CHECK-LABEL: f1:
10 ; CHECK: sgh %r3, 0(%r4)
11 ; CHECK-DAG: stg %r3, 0(%r5)
12 ; CHECK-DAG: lghi %r2, 0
13 ; CHECK-DAG: locghio %r2, 1
14 ; CHECK: br %r14
15   %half = load i16, ptr %src
16   %b = sext i16 %half to i64
17   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
18   %val = extractvalue {i64, i1} %t, 0
19   %obit = extractvalue {i64, i1} %t, 1
20   store i64 %val, ptr %res
21   ret i1 %obit
24 ; Check the high end of the aligned SGH range.
25 define zeroext i1 @f4(i64 %dummy, i64 %a, ptr %src, ptr %res) {
26 ; CHECK-LABEL: f4:
27 ; CHECK: sgh %r3, 524286(%r4)
28 ; CHECK-DAG: stg %r3, 0(%r5)
29 ; CHECK-DAG: lghi %r2, 0
30 ; CHECK-DAG: locghio %r2, 1
31 ; CHECK: br %r14
32   %ptr = getelementptr i16, ptr %src, i64 262143
33   %half = load i16, ptr %ptr
34   %b = sext i16 %half to i64
35   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
36   %val = extractvalue {i64, i1} %t, 0
37   %obit = extractvalue {i64, i1} %t, 1
38   store i64 %val, ptr %res
39   ret i1 %obit
42 ; Check the next halfword up, which needs separate address logic.
43 ; Other sequences besides this one would be OK.
44 define zeroext i1 @f5(i64 %dummy, i64 %a, ptr %src, ptr %res) {
45 ; CHECK-LABEL: f5:
46 ; CHECK: agfi %r4, 524288
47 ; CHECK: sgh %r3, 0(%r4)
48 ; CHECK-DAG: stg %r3, 0(%r5)
49 ; CHECK-DAG: lghi %r2, 0
50 ; CHECK-DAG: locghio %r2, 1
51 ; CHECK: br %r14
52   %ptr = getelementptr i16, ptr %src, i64 262144
53   %half = load i16, ptr %ptr
54   %b = sext i16 %half to i64
55   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
56   %val = extractvalue {i64, i1} %t, 0
57   %obit = extractvalue {i64, i1} %t, 1
58   store i64 %val, ptr %res
59   ret i1 %obit
62 ; Check the high end of the negative aligned SGH range.
63 define zeroext i1 @f6(i64 %dummy, i64 %a, ptr %src, ptr %res) {
64 ; CHECK-LABEL: f6:
65 ; CHECK: sgh %r3, -2(%r4)
66 ; CHECK-DAG: stg %r3, 0(%r5)
67 ; CHECK-DAG: lghi %r2, 0
68 ; CHECK-DAG: locghio %r2, 1
69 ; CHECK: br %r14
70   %ptr = getelementptr i16, ptr %src, i64 -1
71   %half = load i16, ptr %ptr
72   %b = sext i16 %half to i64
73   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
74   %val = extractvalue {i64, i1} %t, 0
75   %obit = extractvalue {i64, i1} %t, 1
76   store i64 %val, ptr %res
77   ret i1 %obit
80 ; Check the low end of the SGH range.
81 define zeroext i1 @f7(i64 %dummy, i64 %a, ptr %src, ptr %res) {
82 ; CHECK-LABEL: f7:
83 ; CHECK: sgh %r3, -524288(%r4)
84 ; CHECK-DAG: stg %r3, 0(%r5)
85 ; CHECK-DAG: lghi %r2, 0
86 ; CHECK-DAG: locghio %r2, 1
87 ; CHECK: br %r14
88   %ptr = getelementptr i16, ptr %src, i64 -262144
89   %half = load i16, ptr %ptr
90   %b = sext i16 %half to i64
91   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
92   %val = extractvalue {i64, i1} %t, 0
93   %obit = extractvalue {i64, i1} %t, 1
94   store i64 %val, ptr %res
95   ret i1 %obit
98 ; Check the next halfword down, which needs separate address logic.
99 ; Other sequences besides this one would be OK.
100 define zeroext i1 @f8(i64 %dummy, i64 %a, ptr %src, ptr %res) {
101 ; CHECK-LABEL: f8:
102 ; CHECK: agfi %r4, -524290
103 ; CHECK: sgh %r3, 0(%r4)
104 ; CHECK-DAG: stg %r3, 0(%r5)
105 ; CHECK-DAG: lghi %r2, 0
106 ; CHECK-DAG: locghio %r2, 1
107 ; CHECK: br %r14
108   %ptr = getelementptr i16, ptr %src, i64 -262145
109   %half = load i16, ptr %ptr
110   %b = sext i16 %half to i64
111   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
112   %val = extractvalue {i64, i1} %t, 0
113   %obit = extractvalue {i64, i1} %t, 1
114   store i64 %val, ptr %res
115   ret i1 %obit
118 ; Check that SGH allows an index.
119 define zeroext i1 @f9(i64 %src, i64 %index, i64 %a, ptr %res) {
120 ; CHECK-LABEL: f9:
121 ; CHECK: sgh %r4, 524284({{%r3,%r2|%r2,%r3}})
122 ; CHECK-DAG: stg %r4, 0(%r5)
123 ; CHECK-DAG: lghi %r2, 0
124 ; CHECK-DAG: locghio %r2, 1
125 ; CHECK: br %r14
126   %add1 = add i64 %src, %index
127   %add2 = add i64 %add1, 524284
128   %ptr = inttoptr i64 %add2 to ptr
129   %half = load i16, ptr %ptr
130   %b = sext i16 %half to i64
131   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
132   %val = extractvalue {i64, i1} %t, 0
133   %obit = extractvalue {i64, i1} %t, 1
134   store i64 %val, ptr %res
135   ret i1 %obit
138 ; Check using the overflow result for a branch.
139 define void @f11(i64 %dummy, i64 %a, ptr %src, ptr %res) {
140 ; CHECK-LABEL: f11:
141 ; CHECK: sgh %r3, 0(%r4)
142 ; CHECK: stg %r3, 0(%r5)
143 ; CHECK: jgo foo@PLT
144 ; CHECK: br %r14
145   %half = load i16, ptr %src
146   %b = sext i16 %half to i64
147   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
148   %val = extractvalue {i64, i1} %t, 0
149   %obit = extractvalue {i64, i1} %t, 1
150   store i64 %val, ptr %res
151   br i1 %obit, label %call, label %exit
153 call:
154   tail call i64 @foo()
155   br label %exit
157 exit:
158   ret void
161 ; ... and the same with the inverted direction.
162 define void @f12(i64 %dummy, i64 %a, ptr %src, ptr %res) {
163 ; CHECK-LABEL: f12:
164 ; CHECK: sgh %r3, 0(%r4)
165 ; CHECK: stg %r3, 0(%r5)
166 ; CHECK: jgno foo@PLT
167 ; CHECK: br %r14
168   %half = load i16, ptr %src
169   %b = sext i16 %half to i64
170   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
171   %val = extractvalue {i64, i1} %t, 0
172   %obit = extractvalue {i64, i1} %t, 1
173   store i64 %val, ptr %res
174   br i1 %obit, label %exit, label %call
176 call:
177   tail call i64 @foo()
178   br label %exit
180 exit:
181   ret void
185 declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone