[SystemZ] Tweak integer comparison code
[oota-llvm.git] / test / CodeGen / SystemZ / cond-store-06.ll
1 ; Test f64 conditional stores that are presented as selects.
2 ;
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5 declare void @foo(double *)
6
7 ; Test with the loaded value first.
8 define void @f1(double *%ptr, double %alt, i32 %limit) {
9 ; CHECK-LABEL: f1:
10 ; CHECK-NOT: %r2
11 ; CHECK: jl [[LABEL:[^ ]*]]
12 ; CHECK-NOT: %r2
13 ; CHECK: std %f0, 0(%r2)
14 ; CHECK: [[LABEL]]:
15 ; CHECK: br %r14
16   %cond = icmp ult i32 %limit, 42
17   %orig = load double *%ptr
18   %res = select i1 %cond, double %orig, double %alt
19   store double %res, double *%ptr
20   ret void
21 }
22
23 ; ...and with the loaded value second
24 define void @f2(double *%ptr, double %alt, i32 %limit) {
25 ; CHECK-LABEL: f2:
26 ; CHECK-NOT: %r2
27 ; CHECK: jhe [[LABEL:[^ ]*]]
28 ; CHECK-NOT: %r2
29 ; CHECK: std %f0, 0(%r2)
30 ; CHECK: [[LABEL]]:
31 ; CHECK: br %r14
32   %cond = icmp ult i32 %limit, 42
33   %orig = load double *%ptr
34   %res = select i1 %cond, double %alt, double %orig
35   store double %res, double *%ptr
36   ret void
37 }
38
39 ; Check the high end of the aligned STD range.
40 define void @f3(double *%base, double %alt, i32 %limit) {
41 ; CHECK-LABEL: f3:
42 ; CHECK-NOT: %r2
43 ; CHECK: jl [[LABEL:[^ ]*]]
44 ; CHECK-NOT: %r2
45 ; CHECK: std %f0, 4088(%r2)
46 ; CHECK: [[LABEL]]:
47 ; CHECK: br %r14
48   %ptr = getelementptr double *%base, i64 511
49   %cond = icmp ult i32 %limit, 42
50   %orig = load double *%ptr
51   %res = select i1 %cond, double %orig, double %alt
52   store double %res, double *%ptr
53   ret void
54 }
55
56 ; Check the next doubleword up, which should use STDY instead of STD.
57 define void @f4(double *%base, double %alt, i32 %limit) {
58 ; CHECK-LABEL: f4:
59 ; CHECK-NOT: %r2
60 ; CHECK: jl [[LABEL:[^ ]*]]
61 ; CHECK-NOT: %r2
62 ; CHECK: stdy %f0, 4096(%r2)
63 ; CHECK: [[LABEL]]:
64 ; CHECK: br %r14
65   %ptr = getelementptr double *%base, i64 512
66   %cond = icmp ult i32 %limit, 42
67   %orig = load double *%ptr
68   %res = select i1 %cond, double %orig, double %alt
69   store double %res, double *%ptr
70   ret void
71 }
72
73 ; Check the high end of the aligned STDY range.
74 define void @f5(double *%base, double %alt, i32 %limit) {
75 ; CHECK-LABEL: f5:
76 ; CHECK-NOT: %r2
77 ; CHECK: jl [[LABEL:[^ ]*]]
78 ; CHECK-NOT: %r2
79 ; CHECK: stdy %f0, 524280(%r2)
80 ; CHECK: [[LABEL]]:
81 ; CHECK: br %r14
82   %ptr = getelementptr double *%base, i64 65535
83   %cond = icmp ult i32 %limit, 42
84   %orig = load double *%ptr
85   %res = select i1 %cond, double %orig, double %alt
86   store double %res, double *%ptr
87   ret void
88 }
89
90 ; Check the next doubleword up, which needs separate address logic.
91 ; Other sequences besides this one would be OK.
92 define void @f6(double *%base, double %alt, i32 %limit) {
93 ; CHECK-LABEL: f6:
94 ; CHECK-NOT: %r2
95 ; CHECK: jl [[LABEL:[^ ]*]]
96 ; CHECK-NOT: %r2
97 ; CHECK: agfi %r2, 524288
98 ; CHECK: std %f0, 0(%r2)
99 ; CHECK: [[LABEL]]:
100 ; CHECK: br %r14
101   %ptr = getelementptr double *%base, i64 65536
102   %cond = icmp ult i32 %limit, 42
103   %orig = load double *%ptr
104   %res = select i1 %cond, double %orig, double %alt
105   store double %res, double *%ptr
106   ret void
107 }
108
109 ; Check the low end of the STDY range.
110 define void @f7(double *%base, double %alt, i32 %limit) {
111 ; CHECK-LABEL: f7:
112 ; CHECK-NOT: %r2
113 ; CHECK: jl [[LABEL:[^ ]*]]
114 ; CHECK-NOT: %r2
115 ; CHECK: stdy %f0, -524288(%r2)
116 ; CHECK: [[LABEL]]:
117 ; CHECK: br %r14
118   %ptr = getelementptr double *%base, i64 -65536
119   %cond = icmp ult i32 %limit, 42
120   %orig = load double *%ptr
121   %res = select i1 %cond, double %orig, double %alt
122   store double %res, double *%ptr
123   ret void
124 }
125
126 ; Check the next doubleword down, which needs separate address logic.
127 ; Other sequences besides this one would be OK.
128 define void @f8(double *%base, double %alt, i32 %limit) {
129 ; CHECK-LABEL: f8:
130 ; CHECK-NOT: %r2
131 ; CHECK: jl [[LABEL:[^ ]*]]
132 ; CHECK-NOT: %r2
133 ; CHECK: agfi %r2, -524296
134 ; CHECK: std %f0, 0(%r2)
135 ; CHECK: [[LABEL]]:
136 ; CHECK: br %r14
137   %ptr = getelementptr double *%base, i64 -65537
138   %cond = icmp ult i32 %limit, 42
139   %orig = load double *%ptr
140   %res = select i1 %cond, double %orig, double %alt
141   store double %res, double *%ptr
142   ret void
143 }
144
145 ; Check that STDY allows an index.
146 define void @f9(i64 %base, i64 %index, double %alt, i32 %limit) {
147 ; CHECK-LABEL: f9:
148 ; CHECK-NOT: %r2
149 ; CHECK: jl [[LABEL:[^ ]*]]
150 ; CHECK-NOT: %r2
151 ; CHECK: stdy %f0, 524287(%r3,%r2)
152 ; CHECK: [[LABEL]]:
153 ; CHECK: br %r14
154   %add1 = add i64 %base, %index
155   %add2 = add i64 %add1, 524287
156   %ptr = inttoptr i64 %add2 to double *
157   %cond = icmp ult i32 %limit, 42
158   %orig = load double *%ptr
159   %res = select i1 %cond, double %orig, double %alt
160   store double %res, double *%ptr
161   ret void
162 }
163
164 ; Check that volatile loads are not matched.
165 define void @f10(double *%ptr, double %alt, i32 %limit) {
166 ; CHECK-LABEL: f10:
167 ; CHECK: ld {{%f[0-5]}}, 0(%r2)
168 ; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
169 ; CHECK: [[LABEL]]:
170 ; CHECK: std {{%f[0-5]}}, 0(%r2)
171 ; CHECK: br %r14
172   %cond = icmp ult i32 %limit, 42
173   %orig = load volatile double *%ptr
174   %res = select i1 %cond, double %orig, double %alt
175   store double %res, double *%ptr
176   ret void
177 }
178
179 ; ...likewise stores.  In this case we should have a conditional load into %f0.
180 define void @f11(double *%ptr, double %alt, i32 %limit) {
181 ; CHECK-LABEL: f11:
182 ; CHECK: jhe [[LABEL:[^ ]*]]
183 ; CHECK: ld %f0, 0(%r2)
184 ; CHECK: [[LABEL]]:
185 ; CHECK: std %f0, 0(%r2)
186 ; CHECK: br %r14
187   %cond = icmp ult i32 %limit, 42
188   %orig = load double *%ptr
189   %res = select i1 %cond, double %orig, double %alt
190   store volatile double %res, double *%ptr
191   ret void
192 }
193
194 ; Try a frame index base.
195 define void @f12(double %alt, i32 %limit) {
196 ; CHECK-LABEL: f12:
197 ; CHECK: brasl %r14, foo@PLT
198 ; CHECK-NOT: %r15
199 ; CHECK: jl [[LABEL:[^ ]*]]
200 ; CHECK-NOT: %r15
201 ; CHECK: std {{%f[0-9]+}}, {{[0-9]+}}(%r15)
202 ; CHECK: [[LABEL]]:
203 ; CHECK: brasl %r14, foo@PLT
204 ; CHECK: br %r14
205   %ptr = alloca double
206   call void @foo(double *%ptr)
207   %cond = icmp ult i32 %limit, 42
208   %orig = load double *%ptr
209   %res = select i1 %cond, double %orig, double %alt
210   store double %res, double *%ptr
211   call void @foo(double *%ptr)
212   ret void
213 }