1; Test 64-bit ordered comparisons that are really between a memory halfword
2; and a constant.
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5
6; Check unsigned comparison near the low end of the CLHHSI range, using zero
7; extension.
8define double @f1(double %a, double %b, i16 *%ptr) {
9; CHECK-LABEL: f1:
10; CHECK: clhhsi 0(%r2), 1
11; CHECK-NEXT: jh
12; CHECK: br %r14
13  %val = load i16 *%ptr
14  %ext = zext i16 %val to i64
15  %cond = icmp ugt i64 %ext, 1
16  %res = select i1 %cond, double %a, double %b
17  ret double %res
18}
19
20; Check unsigned comparison near the low end of the CLHHSI range, using sign
21; extension.
22define double @f2(double %a, double %b, i16 *%ptr) {
23; CHECK-LABEL: f2:
24; CHECK: clhhsi 0(%r2), 1
25; CHECK-NEXT: jh
26; CHECK: br %r14
27  %val = load i16 *%ptr
28  %ext = sext i16 %val to i64
29  %cond = icmp ugt i64 %ext, 1
30  %res = select i1 %cond, double %a, double %b
31  ret double %res
32}
33
34; Check unsigned comparison near the high end of the CLHHSI range, using zero
35; extension.
36define double @f3(double %a, double %b, i16 *%ptr) {
37; CHECK-LABEL: f3:
38; CHECK: clhhsi 0(%r2), 65534
39; CHECK-NEXT: jl
40; CHECK: br %r14
41  %val = load i16 *%ptr
42  %ext = zext i16 %val to i64
43  %cond = icmp ult i64 %ext, 65534
44  %res = select i1 %cond, double %a, double %b
45  ret double %res
46}
47
48; Check unsigned comparison near the high end of the CLHHSI range, using sign
49; extension.
50define double @f4(double %a, double %b, i16 *%ptr) {
51; CHECK-LABEL: f4:
52; CHECK: clhhsi 0(%r2), 65534
53; CHECK-NEXT: jl
54; CHECK: br %r14
55  %val = load i16 *%ptr
56  %ext = sext i16 %val to i64
57  %cond = icmp ult i64 %ext, -2
58  %res = select i1 %cond, double %a, double %b
59  ret double %res
60}
61
62; Check unsigned comparison above the high end of the CLHHSI range, using zero
63; extension.  The condition is always true.
64define double @f5(double %a, double %b, i16 *%ptr) {
65; CHECK-LABEL: f5:
66; CHECK-NOT: clhhsi
67; CHECK: br %r14
68  %val = load i16 *%ptr
69  %ext = zext i16 %val to i64
70  %cond = icmp ult i64 %ext, 65536
71  %res = select i1 %cond, double %a, double %b
72  ret double %res
73}
74
75; When using unsigned comparison with sign extension, equality with values
76; in the range [32768, MAX-32769] is impossible, and ordered comparisons with
77; those values are effectively sign tests.  Since such comparisons are
78; unlikely to occur in practice, we don't bother optimizing the second case,
79; and simply ignore CLHHSI for this range.  First check the low end of the
80; range.
81define double @f6(double %a, double %b, i16 *%ptr) {
82; CHECK-LABEL: f6:
83; CHECK-NOT: clhhsi
84; CHECK: br %r14
85  %val = load i16 *%ptr
86  %ext = sext i16 %val to i64
87  %cond = icmp ult i64 %ext, 32768
88  %res = select i1 %cond, double %a, double %b
89  ret double %res
90}
91
92; ...and then the high end.
93define double @f7(double %a, double %b, i16 *%ptr) {
94; CHECK-LABEL: f7:
95; CHECK-NOT: clhhsi
96; CHECK: br %r14
97  %val = load i16 *%ptr
98  %ext = sext i16 %val to i64
99  %cond = icmp ult i64 %ext, -32769
100  %res = select i1 %cond, double %a, double %b
101  ret double %res
102}
103
104; Check signed comparison near the low end of the CLHHSI range, using zero
105; extension.  This is equivalent to unsigned comparison.
106define double @f8(double %a, double %b, i16 *%ptr) {
107; CHECK-LABEL: f8:
108; CHECK: clhhsi 0(%r2), 1
109; CHECK-NEXT: jh
110; CHECK: br %r14
111  %val = load i16 *%ptr
112  %ext = zext i16 %val to i64
113  %cond = icmp sgt i64 %ext, 1
114  %res = select i1 %cond, double %a, double %b
115  ret double %res
116}
117
118; Check signed comparison near the low end of the CLHHSI range, using sign
119; extension.  This should use CHHSI instead.
120define double @f9(double %a, double %b, i16 *%ptr) {
121; CHECK-LABEL: f9:
122; CHECK: chhsi 0(%r2), 1
123; CHECK-NEXT: jh
124; CHECK: br %r14
125  %val = load i16 *%ptr
126  %ext = sext i16 %val to i64
127  %cond = icmp sgt i64 %ext, 1
128  %res = select i1 %cond, double %a, double %b
129  ret double %res
130}
131
132; Check signed comparison near the high end of the CLHHSI range, using zero
133; extension.  This is equivalent to unsigned comparison.
134define double @f10(double %a, double %b, i16 *%ptr) {
135; CHECK-LABEL: f10:
136; CHECK: clhhsi 0(%r2), 65534
137; CHECK-NEXT: jl
138; CHECK: br %r14
139  %val = load i16 *%ptr
140  %ext = zext i16 %val to i64
141  %cond = icmp slt i64 %ext, 65534
142  %res = select i1 %cond, double %a, double %b
143  ret double %res
144}
145
146; Check signed comparison near the high end of the CLHHSI range, using sign
147; extension.  This should use CHHSI instead.
148define double @f11(double %a, double %b, i16 *%ptr) {
149; CHECK-LABEL: f11:
150; CHECK: chhsi 0(%r2), -2
151; CHECK-NEXT: jl
152; CHECK: br %r14
153  %val = load i16 *%ptr
154  %ext = sext i16 %val to i64
155  %cond = icmp slt i64 %ext, -2
156  %res = select i1 %cond, double %a, double %b
157  ret double %res
158}
159
160; Check signed comparison above the high end of the CLHHSI range, using zero
161; extension.  The condition is always true.
162define double @f12(double %a, double %b, i16 *%ptr) {
163; CHECK-LABEL: f12:
164; CHECK-NOT: cli
165; CHECK: br %r14
166  %val = load i16 *%ptr
167  %ext = zext i16 %val to i64
168  %cond = icmp slt i64 %ext, 65536
169  %res = select i1 %cond, double %a, double %b
170  ret double %res
171}
172
173; Check signed comparison near the high end of the CHHSI range, using sign
174; extension.
175define double @f13(double %a, double %b, i16 *%ptr) {
176; CHECK-LABEL: f13:
177; CHECK: chhsi 0(%r2), 32766
178; CHECK-NEXT: jl
179; CHECK: br %r14
180  %val = load i16 *%ptr
181  %ext = sext i16 %val to i64
182  %cond = icmp slt i64 %ext, 32766
183  %res = select i1 %cond, double %a, double %b
184  ret double %res
185}
186
187; Check signed comparison above the high end of the CHHSI range, using sign
188; extension.  This condition is always true.
189define double @f14(double %a, double %b, i16 *%ptr) {
190; CHECK-LABEL: f14:
191; CHECK-NOT: chhsi
192; CHECK: br %r14
193  %val = load i16 *%ptr
194  %ext = sext i16 %val to i64
195  %cond = icmp slt i64 %ext, 32768
196  %res = select i1 %cond, double %a, double %b
197  ret double %res
198}
199
200; Check signed comparison near the low end of the CHHSI range, using sign
201; extension.
202define double @f15(double %a, double %b, i16 *%ptr) {
203; CHECK-LABEL: f15:
204; CHECK: chhsi 0(%r2), -32767
205; CHECK-NEXT: jh
206; CHECK: br %r14
207  %val = load i16 *%ptr
208  %ext = sext i16 %val to i64
209  %cond = icmp sgt i64 %ext, -32767
210  %res = select i1 %cond, double %a, double %b
211  ret double %res
212}
213
214; Check signed comparison below the low end of the CHHSI range, using sign
215; extension.  This condition is always true.
216define double @f16(double %a, double %b, i16 *%ptr) {
217; CHECK-LABEL: f16:
218; CHECK-NOT: chhsi
219; CHECK: br %r14
220  %val = load i16 *%ptr
221  %ext = sext i16 %val to i64
222  %cond = icmp sgt i64 %ext, -32769
223  %res = select i1 %cond, double %a, double %b
224  ret double %res
225}
226