1; Test negative integer absolute.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5; Test i32->i32 negative absolute using slt.
6define i32 @f1(i32 %val) {
7; CHECK-LABEL: f1:
8; CHECK: lnr %r2, %r2
9; CHECK: br %r14
10  %cmp = icmp slt i32 %val, 0
11  %neg = sub i32 0, %val
12  %abs = select i1 %cmp, i32 %neg, i32 %val
13  %res = sub i32 0, %abs
14  ret i32 %res
15}
16
17; Test i32->i32 negative absolute using sle.
18define i32 @f2(i32 %val) {
19; CHECK-LABEL: f2:
20; CHECK: lnr %r2, %r2
21; CHECK: br %r14
22  %cmp = icmp sle i32 %val, 0
23  %neg = sub i32 0, %val
24  %abs = select i1 %cmp, i32 %neg, i32 %val
25  %res = sub i32 0, %abs
26  ret i32 %res
27}
28
29; Test i32->i32 negative absolute using sgt.
30define i32 @f3(i32 %val) {
31; CHECK-LABEL: f3:
32; CHECK: lnr %r2, %r2
33; CHECK: br %r14
34  %cmp = icmp sgt i32 %val, 0
35  %neg = sub i32 0, %val
36  %abs = select i1 %cmp, i32 %val, i32 %neg
37  %res = sub i32 0, %abs
38  ret i32 %res
39}
40
41; Test i32->i32 negative absolute using sge.
42define i32 @f4(i32 %val) {
43; CHECK-LABEL: f4:
44; CHECK: lnr %r2, %r2
45; CHECK: br %r14
46  %cmp = icmp sge i32 %val, 0
47  %neg = sub i32 0, %val
48  %abs = select i1 %cmp, i32 %val, i32 %neg
49  %res = sub i32 0, %abs
50  ret i32 %res
51}
52
53; Test i32->i64 negative absolute.
54define i64 @f5(i32 %val) {
55; CHECK-LABEL: f5:
56; CHECK: lngfr %r2, %r2
57; CHECK: br %r14
58  %ext = sext i32 %val to i64
59  %cmp = icmp slt i64 %ext, 0
60  %neg = sub i64 0, %ext
61  %abs = select i1 %cmp, i64 %neg, i64 %ext
62  %res = sub i64 0, %abs
63  ret i64 %res
64}
65
66; Test i32->i64 negative absolute that uses an "in-register" form of
67; sign extension.
68define i64 @f6(i64 %val) {
69; CHECK-LABEL: f6:
70; CHECK: lngfr %r2, %r2
71; CHECK: br %r14
72  %trunc = trunc i64 %val to i32
73  %ext = sext i32 %trunc to i64
74  %cmp = icmp slt i64 %ext, 0
75  %neg = sub i64 0, %ext
76  %abs = select i1 %cmp, i64 %neg, i64 %ext
77  %res = sub i64 0, %abs
78  ret i64 %res
79}
80
81; Test i64 negative absolute.
82define i64 @f7(i64 %val) {
83; CHECK-LABEL: f7:
84; CHECK: lngr %r2, %r2
85; CHECK: br %r14
86  %cmp = icmp slt i64 %val, 0
87  %neg = sub i64 0, %val
88  %abs = select i1 %cmp, i64 %neg, i64 %val
89  %res = sub i64 0, %abs
90  ret i64 %res
91}
92
93; Test another form of f6, which is that produced by InstCombine.
94define i64 @f8(i64 %val) {
95; CHECK-LABEL: f8:
96; CHECK: lngfr %r2, %r2
97; CHECK: br %r14
98  %shl = shl i64 %val, 32
99  %ashr = ashr i64 %shl, 32
100  %neg = sub i64 0, %ashr
101  %cmp = icmp slt i64 %shl, 0
102  %abs = select i1 %cmp, i64 %neg, i64 %ashr
103  %res = sub i64 0, %abs
104  ret i64 %res
105}
106
107; Try again with sle rather than slt.
108define i64 @f9(i64 %val) {
109; CHECK-LABEL: f9:
110; CHECK: lngfr %r2, %r2
111; CHECK: br %r14
112  %shl = shl i64 %val, 32
113  %ashr = ashr i64 %shl, 32
114  %neg = sub i64 0, %ashr
115  %cmp = icmp sle i64 %shl, 0
116  %abs = select i1 %cmp, i64 %neg, i64 %ashr
117  %res = sub i64 0, %abs
118  ret i64 %res
119}
120
121; Repeat f8 with the operands reversed.
122define i64 @f10(i64 %val) {
123; CHECK-LABEL: f10:
124; CHECK: lngfr %r2, %r2
125; CHECK: br %r14
126  %shl = shl i64 %val, 32
127  %ashr = ashr i64 %shl, 32
128  %neg = sub i64 0, %ashr
129  %cmp = icmp sgt i64 %shl, 0
130  %abs = select i1 %cmp, i64 %ashr, i64 %neg
131  %res = sub i64 0, %abs
132  ret i64 %res
133}
134
135; Try again with sge rather than sgt.
136define i64 @f11(i64 %val) {
137; CHECK-LABEL: f11:
138; CHECK: lngfr %r2, %r2
139; CHECK: br %r14
140  %shl = shl i64 %val, 32
141  %ashr = ashr i64 %shl, 32
142  %neg = sub i64 0, %ashr
143  %cmp = icmp sge i64 %shl, 0
144  %abs = select i1 %cmp, i64 %ashr, i64 %neg
145  %res = sub i64 0, %abs
146  ret i64 %res
147}
148
149; Repeat f8 with the negation coming from swapped operands.
150define i64 @f12(i64 %val) {
151; CHECK-LABEL: f12:
152; CHECK: lngfr %r2, %r2
153; CHECK: br %r14
154  %shl = shl i64 %val, 32
155  %ashr = ashr i64 %shl, 32
156  %neg = sub i64 0, %ashr
157  %cmp = icmp slt i64 %shl, 0
158  %negabs = select i1 %cmp, i64 %ashr, i64 %neg
159  ret i64 %negabs
160}
161
162; Likewise f9.
163define i64 @f13(i64 %val) {
164; CHECK-LABEL: f13:
165; CHECK: lngfr %r2, %r2
166; CHECK: br %r14
167  %shl = shl i64 %val, 32
168  %ashr = ashr i64 %shl, 32
169  %neg = sub i64 0, %ashr
170  %cmp = icmp sle i64 %shl, 0
171  %negabs = select i1 %cmp, i64 %ashr, i64 %neg
172  ret i64 %negabs
173}
174
175; Likewise f10.
176define i64 @f14(i64 %val) {
177; CHECK-LABEL: f14:
178; CHECK: lngfr %r2, %r2
179; CHECK: br %r14
180  %shl = shl i64 %val, 32
181  %ashr = ashr i64 %shl, 32
182  %neg = sub i64 0, %ashr
183  %cmp = icmp sgt i64 %shl, 0
184  %negabs = select i1 %cmp, i64 %neg, i64 %ashr
185  ret i64 %negabs
186}
187
188; Likewise f11.
189define i64 @f15(i64 %val) {
190; CHECK-LABEL: f15:
191; CHECK: lngfr %r2, %r2
192; CHECK: br %r14
193  %shl = shl i64 %val, 32
194  %ashr = ashr i64 %shl, 32
195  %neg = sub i64 0, %ashr
196  %cmp = icmp sge i64 %shl, 0
197  %negabs = select i1 %cmp, i64 %neg, i64 %ashr
198  ret i64 %negabs
199}
200
201; Repeat f5 with the comparison on the unextended value.
202define i64 @f16(i32 %val) {
203; CHECK-LABEL: f16:
204; CHECK: lngfr %r2, %r2
205; CHECK: br %r14
206  %ext = sext i32 %val to i64
207  %cmp = icmp slt i32 %val, 0
208  %neg = sub i64 0, %ext
209  %abs = select i1 %cmp, i64 %neg, i64 %ext
210  %res = sub i64 0, %abs
211  ret i64 %res
212}
213
214; And again with the negation coming from swapped operands.
215define i64 @f17(i32 %val) {
216; CHECK-LABEL: f17:
217; CHECK: lngfr %r2, %r2
218; CHECK: br %r14
219  %ext = sext i32 %val to i64
220  %cmp = icmp slt i32 %val, 0
221  %neg = sub i64 0, %ext
222  %abs = select i1 %cmp, i64 %ext, i64 %neg
223  ret i64 %abs
224}
225