1; Test 32-bit signed comparisons between memory and a constant.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5; Check ordered comparisons with 0.
6define double @f1(double %a, double %b, i32 *%ptr) {
7; CHECK-LABEL: f1:
8; CHECK: chsi 0(%r2), 0
9; CHECK-NEXT: blr %r14
10; CHECK: ldr %f0, %f2
11; CHECK: br %r14
12  %val = load i32 , i32 *%ptr
13  %cond = icmp slt i32 %val, 0
14  %res = select i1 %cond, double %a, double %b
15  ret double %res
16}
17
18; Check ordered comparisons with 1.
19define double @f2(double %a, double %b, i32 *%ptr) {
20; CHECK-LABEL: f2:
21; CHECK: chsi 0(%r2), 0
22; CHECK-NEXT: bler %r14
23; CHECK: ldr %f0, %f2
24; CHECK: br %r14
25  %val = load i32 , i32 *%ptr
26  %cond = icmp slt i32 %val, 1
27  %res = select i1 %cond, double %a, double %b
28  ret double %res
29}
30
31; Check ordered comparisons with the high end of the signed 16-bit range.
32define double @f3(double %a, double %b, i32 *%ptr) {
33; CHECK-LABEL: f3:
34; CHECK: chsi 0(%r2), 32767
35; CHECK-NEXT: blr %r14
36; CHECK: ldr %f0, %f2
37; CHECK: br %r14
38  %val = load i32 , i32 *%ptr
39  %cond = icmp slt i32 %val, 32767
40  %res = select i1 %cond, double %a, double %b
41  ret double %res
42}
43
44; Check the next value up, which can't use CHSI.
45define double @f4(double %a, double %b, i32 *%ptr) {
46; CHECK-LABEL: f4:
47; CHECK-NOT: chsi
48; CHECK: br %r14
49  %val = load i32 , i32 *%ptr
50  %cond = icmp slt i32 %val, 32768
51  %res = select i1 %cond, double %a, double %b
52  ret double %res
53}
54
55; Check ordered comparisons with -1.
56define double @f5(double %a, double %b, i32 *%ptr) {
57; CHECK-LABEL: f5:
58; CHECK: chsi 0(%r2), -1
59; CHECK-NEXT: blr %r14
60; CHECK: ldr %f0, %f2
61; CHECK: br %r14
62  %val = load i32 , i32 *%ptr
63  %cond = icmp slt i32 %val, -1
64  %res = select i1 %cond, double %a, double %b
65  ret double %res
66}
67
68; Check ordered comparisons with the low end of the 16-bit signed range.
69define double @f6(double %a, double %b, i32 *%ptr) {
70; CHECK-LABEL: f6:
71; CHECK: chsi 0(%r2), -32768
72; CHECK-NEXT: blr %r14
73; CHECK: ldr %f0, %f2
74; CHECK: br %r14
75  %val = load i32 , i32 *%ptr
76  %cond = icmp slt i32 %val, -32768
77  %res = select i1 %cond, double %a, double %b
78  ret double %res
79}
80
81; Check the next value down, which can't use CHSI.
82define double @f7(double %a, double %b, i32 *%ptr) {
83; CHECK-LABEL: f7:
84; CHECK-NOT: chsi
85; CHECK: br %r14
86  %val = load i32 , i32 *%ptr
87  %cond = icmp slt i32 %val, -32769
88  %res = select i1 %cond, double %a, double %b
89  ret double %res
90}
91
92; Check equality comparisons with 0.
93define double @f8(double %a, double %b, i32 *%ptr) {
94; CHECK-LABEL: f8:
95; CHECK: chsi 0(%r2), 0
96; CHECK-NEXT: ber %r14
97; CHECK: ldr %f0, %f2
98; CHECK: br %r14
99  %val = load i32 , i32 *%ptr
100  %cond = icmp eq i32 %val, 0
101  %res = select i1 %cond, double %a, double %b
102  ret double %res
103}
104
105; Check equality comparisons with 1.
106define double @f9(double %a, double %b, i32 *%ptr) {
107; CHECK-LABEL: f9:
108; CHECK: chsi 0(%r2), 1
109; CHECK-NEXT: ber %r14
110; CHECK: ldr %f0, %f2
111; CHECK: br %r14
112  %val = load i32 , i32 *%ptr
113  %cond = icmp eq i32 %val, 1
114  %res = select i1 %cond, double %a, double %b
115  ret double %res
116}
117
118; Check equality comparisons with the high end of the signed 16-bit range.
119define double @f10(double %a, double %b, i32 *%ptr) {
120; CHECK-LABEL: f10:
121; CHECK: chsi 0(%r2), 32767
122; CHECK-NEXT: ber %r14
123; CHECK: ldr %f0, %f2
124; CHECK: br %r14
125  %val = load i32 , i32 *%ptr
126  %cond = icmp eq i32 %val, 32767
127  %res = select i1 %cond, double %a, double %b
128  ret double %res
129}
130
131; Check the next value up, which can't use CHSI.
132define double @f11(double %a, double %b, i32 *%ptr) {
133; CHECK-LABEL: f11:
134; CHECK-NOT: chsi
135; CHECK: br %r14
136  %val = load i32 , i32 *%ptr
137  %cond = icmp eq i32 %val, 32768
138  %res = select i1 %cond, double %a, double %b
139  ret double %res
140}
141
142; Check equality comparisons with -1.
143define double @f12(double %a, double %b, i32 *%ptr) {
144; CHECK-LABEL: f12:
145; CHECK: chsi 0(%r2), -1
146; CHECK-NEXT: ber %r14
147; CHECK: ldr %f0, %f2
148; CHECK: br %r14
149  %val = load i32 , i32 *%ptr
150  %cond = icmp eq i32 %val, -1
151  %res = select i1 %cond, double %a, double %b
152  ret double %res
153}
154
155; Check equality comparisons with the low end of the 16-bit signed range.
156define double @f13(double %a, double %b, i32 *%ptr) {
157; CHECK-LABEL: f13:
158; CHECK: chsi 0(%r2), -32768
159; CHECK-NEXT: ber %r14
160; CHECK: ldr %f0, %f2
161; CHECK: br %r14
162  %val = load i32 , i32 *%ptr
163  %cond = icmp eq i32 %val, -32768
164  %res = select i1 %cond, double %a, double %b
165  ret double %res
166}
167
168; Check the next value down, which should be treated as a positive value.
169define double @f14(double %a, double %b, i32 *%ptr) {
170; CHECK-LABEL: f14:
171; CHECK-NOT: chsi
172; CHECK: br %r14
173  %val = load i32 , i32 *%ptr
174  %cond = icmp eq i32 %val, -32769
175  %res = select i1 %cond, double %a, double %b
176  ret double %res
177}
178
179; Check the high end of the CHSI range.
180define double @f15(double %a, double %b, i32 %i1, i32 *%base) {
181; CHECK-LABEL: f15:
182; CHECK: chsi 4092(%r3), 0
183; CHECK-NEXT: blr %r14
184; CHECK: ldr %f0, %f2
185; CHECK: br %r14
186  %ptr = getelementptr i32, i32 *%base, i64 1023
187  %val = load i32 , i32 *%ptr
188  %cond = icmp slt i32 %val, 0
189  %res = select i1 %cond, double %a, double %b
190  ret double %res
191}
192
193; Check the next word up, which needs separate address logic,
194define double @f16(double %a, double %b, i32 *%base) {
195; CHECK-LABEL: f16:
196; CHECK: aghi %r2, 4096
197; CHECK: chsi 0(%r2), 0
198; CHECK-NEXT: blr %r14
199; CHECK: ldr %f0, %f2
200; CHECK: br %r14
201  %ptr = getelementptr i32, i32 *%base, i64 1024
202  %val = load i32 , i32 *%ptr
203  %cond = icmp slt i32 %val, 0
204  %res = select i1 %cond, double %a, double %b
205  ret double %res
206}
207
208; Check negative offsets, which also need separate address logic.
209define double @f17(double %a, double %b, i32 *%base) {
210; CHECK-LABEL: f17:
211; CHECK: aghi %r2, -4
212; CHECK: chsi 0(%r2), 0
213; CHECK-NEXT: blr %r14
214; CHECK: ldr %f0, %f2
215; CHECK: br %r14
216  %ptr = getelementptr i32, i32 *%base, i64 -1
217  %val = load i32 , i32 *%ptr
218  %cond = icmp slt i32 %val, 0
219  %res = select i1 %cond, double %a, double %b
220  ret double %res
221}
222
223; Check that CHSI does not allow indices.
224define double @f18(double %a, double %b, i64 %base, i64 %index) {
225; CHECK-LABEL: f18:
226; CHECK: agr {{%r2, %r3|%r3, %r2}}
227; CHECK: chsi 0({{%r[23]}}), 0
228; CHECK-NEXT: blr %r14
229; CHECK: ldr %f0, %f2
230; CHECK: br %r14
231  %add = add i64 %base, %index
232  %ptr = inttoptr i64 %add to i32 *
233  %val = load i32 , i32 *%ptr
234  %cond = icmp slt i32 %val, 0
235  %res = select i1 %cond, double %a, double %b
236  ret double %res
237}
238