R600: Fix miscompiles when BFE has multiple uses
[oota-llvm.git] / test / CodeGen / SystemZ / int-cmp-48.ll
1 ; Test the use of TM and TMY.
2 ;
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
4
5 @g = global i32 0
6
7 ; Check a simple branching use of TM.
8 define void @f1(i8 *%src) {
9 ; CHECK-LABEL: f1:
10 ; CHECK: tm 0(%r2), 1
11 ; CHECK: je {{\.L.*}}
12 ; CHECK: br %r14
13 entry:
14   %byte = load i8 *%src
15   %and = and i8 %byte, 1
16   %cmp = icmp eq i8 %and, 0
17   br i1 %cmp, label %exit, label %store
18
19 store:
20   store i32 1, i32 *@g
21   br label %exit
22
23 exit:
24   ret void
25 }
26
27
28 ; Check that we do not fold across an aliasing store.
29 define void @f2(i8 *%src) {
30 ; CHECK-LABEL: f2:
31 ; CHECK: llc [[REG:%r[0-5]]], 0(%r2)
32 ; CHECK: mvi 0(%r2), 0
33 ; CHECK: tmll [[REG]], 1
34 ; CHECK: je {{\.L.*}}
35 ; CHECK: br %r14
36 entry:
37   %byte = load i8 *%src
38   store i8 0, i8 *%src
39   %and = and i8 %byte, 1
40   %cmp = icmp eq i8 %and, 0
41   br i1 %cmp, label %exit, label %store
42
43 store:
44   store i32 1, i32 *@g
45   br label %exit
46
47 exit:
48   ret void
49 }
50
51 ; Check a simple select-based use of TM.
52 define double @f3(i8 *%src, double %a, double %b) {
53 ; CHECK-LABEL: f3:
54 ; CHECK: tm 0(%r2), 1
55 ; CHECK: je {{\.L.*}}
56 ; CHECK: br %r14
57   %byte = load i8 *%src
58   %and = and i8 %byte, 1
59   %cmp = icmp eq i8 %and, 0
60   %res = select i1 %cmp, double %b, double %a
61   ret double %res
62 }
63
64 ; Check that we do not fold across an aliasing store.
65 define double @f4(i8 *%src, double %a, double %b) {
66 ; CHECK-LABEL: f4:
67 ; CHECK: tm 0(%r2), 1
68 ; CHECK: je {{\.L.*}}
69 ; CHECK: mvi 0(%r2), 0
70 ; CHECK: br %r14
71   %byte = load i8 *%src
72   %and = and i8 %byte, 1
73   %cmp = icmp eq i8 %and, 0
74   %res = select i1 %cmp, double %b, double %a
75   store i8 0, i8 *%src
76   ret double %res
77 }
78
79 ; Check an inequality check.
80 define double @f5(i8 *%src, double %a, double %b) {
81 ; CHECK-LABEL: f5:
82 ; CHECK: tm 0(%r2), 1
83 ; CHECK: jne {{\.L.*}}
84 ; CHECK: br %r14
85   %byte = load i8 *%src
86   %and = and i8 %byte, 1
87   %cmp = icmp ne i8 %and, 0
88   %res = select i1 %cmp, double %b, double %a
89   ret double %res
90 }
91
92 ; Check that we can also use TM for equality comparisons with the mask.
93 define double @f6(i8 *%src, double %a, double %b) {
94 ; CHECK-LABEL: f6:
95 ; CHECK: tm 0(%r2), 254
96 ; CHECK: jo {{\.L.*}}
97 ; CHECK: br %r14
98   %byte = load i8 *%src
99   %and = and i8 %byte, 254
100   %cmp = icmp eq i8 %and, 254
101   %res = select i1 %cmp, double %b, double %a
102   ret double %res
103 }
104
105 ; Check inequality comparisons with the mask.
106 define double @f7(i8 *%src, double %a, double %b) {
107 ; CHECK-LABEL: f7:
108 ; CHECK: tm 0(%r2), 254
109 ; CHECK: jno {{\.L.*}}
110 ; CHECK: br %r14
111   %byte = load i8 *%src
112   %and = and i8 %byte, 254
113   %cmp = icmp ne i8 %and, 254
114   %res = select i1 %cmp, double %b, double %a
115   ret double %res
116 }
117
118 ; Check that we do not use the memory TM instruction when CC is being tested
119 ; for 2.
120 define double @f8(i8 *%src, double %a, double %b) {
121 ; CHECK-LABEL: f8:
122 ; CHECK: llc [[REG:%r[0-5]]], 0(%r2)
123 ; CHECK: tmll [[REG]], 3
124 ; CHECK: jh {{\.L.*}}
125 ; CHECK: br %r14
126   %byte = load i8 *%src
127   %and = and i8 %byte, 3
128   %cmp = icmp eq i8 %and, 2
129   %res = select i1 %cmp, double %b, double %a
130   ret double %res
131 }
132
133 ; ...likewise 1.
134 define double @f9(i8 *%src, double %a, double %b) {
135 ; CHECK-LABEL: f9:
136 ; CHECK: llc [[REG:%r[0-5]]], 0(%r2)
137 ; CHECK: tmll [[REG]], 3
138 ; CHECK: jl {{\.L.*}}
139 ; CHECK: br %r14
140   %byte = load i8 *%src
141   %and = and i8 %byte, 3
142   %cmp = icmp eq i8 %and, 1
143   %res = select i1 %cmp, double %b, double %a
144   ret double %res
145 }
146
147 ; Check the high end of the TM range.
148 define double @f10(i8 *%src, double %a, double %b) {
149 ; CHECK-LABEL: f10:
150 ; CHECK: tm 4095(%r2), 1
151 ; CHECK: je {{\.L.*}}
152 ; CHECK: br %r14
153   %ptr = getelementptr i8 *%src, i64 4095
154   %byte = load i8 *%ptr
155   %and = and i8 %byte, 1
156   %cmp = icmp eq i8 %and, 0
157   %res = select i1 %cmp, double %b, double %a
158   ret double %res
159 }
160
161 ; Check the low end of the positive TMY range.
162 define double @f11(i8 *%src, double %a, double %b) {
163 ; CHECK-LABEL: f11:
164 ; CHECK: tmy 4096(%r2), 1
165 ; CHECK: je {{\.L.*}}
166 ; CHECK: br %r14
167   %ptr = getelementptr i8 *%src, i64 4096
168   %byte = load i8 *%ptr
169   %and = and i8 %byte, 1
170   %cmp = icmp eq i8 %and, 0
171   %res = select i1 %cmp, double %b, double %a
172   ret double %res
173 }
174
175 ; Check the high end of the TMY range.
176 define double @f12(i8 *%src, double %a, double %b) {
177 ; CHECK-LABEL: f12:
178 ; CHECK: tmy 524287(%r2), 1
179 ; CHECK: je {{\.L.*}}
180 ; CHECK: br %r14
181   %ptr = getelementptr i8 *%src, i64 524287
182   %byte = load i8 *%ptr
183   %and = and i8 %byte, 1
184   %cmp = icmp eq i8 %and, 0
185   %res = select i1 %cmp, double %b, double %a
186   ret double %res
187 }
188
189 ; Check the next byte up, which needs separate address logic.
190 define double @f13(i8 *%src, double %a, double %b) {
191 ; CHECK-LABEL: f13:
192 ; CHECK: agfi %r2, 524288
193 ; CHECK: tm 0(%r2), 1
194 ; CHECK: je {{\.L.*}}
195 ; CHECK: br %r14
196   %ptr = getelementptr i8 *%src, i64 524288
197   %byte = load i8 *%ptr
198   %and = and i8 %byte, 1
199   %cmp = icmp eq i8 %and, 0
200   %res = select i1 %cmp, double %b, double %a
201   ret double %res
202 }
203
204 ; Check the low end of the TMY range.
205 define double @f14(i8 *%src, double %a, double %b) {
206 ; CHECK-LABEL: f14:
207 ; CHECK: tmy -524288(%r2), 1
208 ; CHECK: je {{\.L.*}}
209 ; CHECK: br %r14
210   %ptr = getelementptr i8 *%src, i64 -524288
211   %byte = load i8 *%ptr
212   %and = and i8 %byte, 1
213   %cmp = icmp eq i8 %and, 0
214   %res = select i1 %cmp, double %b, double %a
215   ret double %res
216 }
217
218 ; Check the next byte down, which needs separate address logic.
219 define double @f15(i8 *%src, double %a, double %b) {
220 ; CHECK-LABEL: f15:
221 ; CHECK: agfi %r2, -524289
222 ; CHECK: tm 0(%r2), 1
223 ; CHECK: je {{\.L.*}}
224 ; CHECK: br %r14
225   %ptr = getelementptr i8 *%src, i64 -524289
226   %byte = load i8 *%ptr
227   %and = and i8 %byte, 1
228   %cmp = icmp eq i8 %and, 0
229   %res = select i1 %cmp, double %b, double %a
230   ret double %res
231 }
232
233 ; Check that TM(Y) does not allow an index
234 define double @f16(i8 *%src, i64 %index, double %a, double %b) {
235 ; CHECK-LABEL: f16:
236 ; CHECK: tm 0({{%r[1-5]}}), 1
237 ; CHECK: je {{\.L.*}}
238 ; CHECK: br %r14
239   %ptr = getelementptr i8 *%src, i64 %index
240   %byte = load i8 *%ptr
241   %and = and i8 %byte, 1
242   %cmp = icmp eq i8 %and, 0
243   %res = select i1 %cmp, double %b, double %a
244   ret double %res
245 }