1; Test 64-bit ordered comparisons that are really between a memory byte
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 CLI range, using zero
7; extension.
8define double @f1(double %a, double %b, i8 *%ptr) {
9; CHECK-LABEL: f1:
10; CHECK: cli 0(%r2), 1
11; CHECK-NEXT: jh
12; CHECK: br %r14
13  %val = load i8 *%ptr
14  %ext = zext i8 %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 CLI range, using sign
21; extension.
22define double @f2(double %a, double %b, i8 *%ptr) {
23; CHECK-LABEL: f2:
24; CHECK: cli 0(%r2), 1
25; CHECK-NEXT: jh
26; CHECK: br %r14
27  %val = load i8 *%ptr
28  %ext = sext i8 %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 CLI range, using zero
35; extension.
36define double @f3(double %a, double %b, i8 *%ptr) {
37; CHECK-LABEL: f3:
38; CHECK: cli 0(%r2), 254
39; CHECK-NEXT: jl
40; CHECK: br %r14
41  %val = load i8 *%ptr
42  %ext = zext i8 %val to i64
43  %cond = icmp ult i64 %ext, 254
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 CLI range, using sign
49; extension.
50define double @f4(double %a, double %b, i8 *%ptr) {
51; CHECK-LABEL: f4:
52; CHECK: cli 0(%r2), 254
53; CHECK-NEXT: jl
54; CHECK: br %r14
55  %val = load i8 *%ptr
56  %ext = sext i8 %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 CLI range, using zero
63; extension.  The condition is always true.
64define double @f5(double %a, double %b, i8 *%ptr) {
65; CHECK-LABEL: f5:
66; CHECK-NOT: cli
67; CHECK: br %r14
68  %val = load i8 *%ptr
69  %ext = zext i8 %val to i64
70  %cond = icmp ult i64 %ext, 256
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 [128, MAX-129] 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 CLI for this range.  First check the low end of the range.
80define double @f6(double %a, double %b, i8 *%ptr) {
81; CHECK-LABEL: f6:
82; CHECK-NOT: cli
83; CHECK: br %r14
84  %val = load i8 *%ptr
85  %ext = sext i8 %val to i64
86  %cond = icmp ult i64 %ext, 128
87  %res = select i1 %cond, double %a, double %b
88  ret double %res
89}
90
91; ...and then the high end.
92define double @f7(double %a, double %b, i8 *%ptr) {
93; CHECK-LABEL: f7:
94; CHECK-NOT: cli
95; CHECK: br %r14
96  %val = load i8 *%ptr
97  %ext = sext i8 %val to i64
98  %cond = icmp ult i64 %ext, -129
99  %res = select i1 %cond, double %a, double %b
100  ret double %res
101}
102
103; Check signed comparison near the low end of the CLI range, using zero
104; extension.  This is equivalent to unsigned comparison.
105define double @f8(double %a, double %b, i8 *%ptr) {
106; CHECK-LABEL: f8:
107; CHECK: cli 0(%r2), 1
108; CHECK-NEXT: jh
109; CHECK: br %r14
110  %val = load i8 *%ptr
111  %ext = zext i8 %val to i64
112  %cond = icmp sgt i64 %ext, 1
113  %res = select i1 %cond, double %a, double %b
114  ret double %res
115}
116
117; Check signed comparison near the low end of the CLI range, using sign
118; extension.  This cannot use CLI.
119define double @f9(double %a, double %b, i8 *%ptr) {
120; CHECK-LABEL: f9:
121; CHECK-NOT: cli
122; CHECK: br %r14
123  %val = load i8 *%ptr
124  %ext = sext i8 %val to i64
125  %cond = icmp sgt i64 %ext, 1
126  %res = select i1 %cond, double %a, double %b
127  ret double %res
128}
129
130; Check signed comparison near the high end of the CLI range, using zero
131; extension.  This is equivalent to unsigned comparison.
132define double @f10(double %a, double %b, i8 *%ptr) {
133; CHECK-LABEL: f10:
134; CHECK: cli 0(%r2), 254
135; CHECK-NEXT: jl
136; CHECK: br %r14
137  %val = load i8 *%ptr
138  %ext = zext i8 %val to i64
139  %cond = icmp slt i64 %ext, 254
140  %res = select i1 %cond, double %a, double %b
141  ret double %res
142}
143
144; Check signed comparison near the high end of the CLI range, using sign
145; extension.  This cannot use CLI.
146define double @f11(double %a, double %b, i8 *%ptr) {
147; CHECK-LABEL: f11:
148; CHECK-NOT: cli
149; CHECK: br %r14
150  %val = load i8 *%ptr
151  %ext = sext i8 %val to i64
152  %cond = icmp slt i64 %ext, -2
153  %res = select i1 %cond, double %a, double %b
154  ret double %res
155}
156
157; Check signed comparison above the high end of the CLI range, using zero
158; extension.  The condition is always true.
159define double @f12(double %a, double %b, i8 *%ptr) {
160; CHECK-LABEL: f12:
161; CHECK-NOT: cli
162; CHECK: br %r14
163  %val = load i8 *%ptr
164  %ext = zext i8 %val to i64
165  %cond = icmp slt i64 %ext, 256
166  %res = select i1 %cond, double %a, double %b
167  ret double %res
168}
169
170; Check tests for nonnegative values.
171define double @f13(double %a, double %b, i8 *%ptr) {
172; CHECK-LABEL: f13:
173; CHECK: cli 0(%r2), 128
174; CHECK-NEXT: jl
175; CHECK: br %r14
176  %val = load i8 *%ptr
177  %ext = sext i8 %val to i64
178  %cond = icmp sge i64 %ext, 0
179  %res = select i1 %cond, double %a, double %b
180  ret double %res
181}
182
183; ...and another form
184define double @f14(double %a, double %b, i8 *%ptr) {
185; CHECK-LABEL: f14:
186; CHECK: cli 0(%r2), 128
187; CHECK-NEXT: jl
188; CHECK: br %r14
189  %val = load i8 *%ptr
190  %ext = sext i8 %val to i64
191  %cond = icmp sgt i64 %ext, -1
192  %res = select i1 %cond, double %a, double %b
193  ret double %res
194}
195
196; Check tests for negative values.
197define double @f15(double %a, double %b, i8 *%ptr) {
198; CHECK-LABEL: f15:
199; CHECK: cli 0(%r2), 127
200; CHECK-NEXT: jh
201; CHECK: br %r14
202  %val = load i8 *%ptr
203  %ext = sext i8 %val to i64
204  %cond = icmp slt i64 %ext, 0
205  %res = select i1 %cond, double %a, double %b
206  ret double %res
207}
208
209; ...and another form
210define double @f16(double %a, double %b, i8 *%ptr) {
211; CHECK-LABEL: f16:
212; CHECK: cli 0(%r2), 127
213; CHECK-NEXT: jh
214; CHECK: br %r14
215  %val = load i8 *%ptr
216  %ext = sext i8 %val to i64
217  %cond = icmp sle i64 %ext, -1
218  %res = select i1 %cond, double %a, double %b
219  ret double %res
220}
221