1 ; Test the use of TM and TMY.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
7 ; Check a simple branching use of TM.
8 define void @f1(i8 *%src) {
14 %byte = load i8, i8 *%src
15 %and = and i8 %byte, 1
16 %cmp = icmp eq i8 %and, 0
17 br i1 %cmp, label %exit, label %store
28 ; Check that we do not fold across an aliasing store.
29 define void @f2(i8 *%src) {
32 ; CHECK: mvi 0(%r2), 0
36 %byte = load i8, i8 *%src
38 %and = and i8 %byte, 1
39 %cmp = icmp eq i8 %and, 0
40 br i1 %cmp, label %exit, label %store
50 ; Check a simple select-based use of TM.
51 define double @f3(i8 *%src, double %a, double %b) {
56 %byte = load i8, i8 *%src
57 %and = and i8 %byte, 1
58 %cmp = icmp eq i8 %and, 0
59 %res = select i1 %cmp, double %b, double %a
63 ; Check that we do not fold across an aliasing store.
64 define double @f4(i8 *%src, double %a, double %b) {
68 ; CHECK: mvi 0(%r2), 0
70 %byte = load i8, i8 *%src
71 %and = and i8 %byte, 1
72 %cmp = icmp eq i8 %and, 0
73 %res = select i1 %cmp, double %b, double %a
78 ; Check an inequality check.
79 define double @f5(i8 *%src, double %a, double %b) {
82 ; CHECK: jne {{\.L.*}}
84 %byte = load i8, i8 *%src
85 %and = and i8 %byte, 1
86 %cmp = icmp ne i8 %and, 0
87 %res = select i1 %cmp, double %b, double %a
91 ; Check that we can also use TM for equality comparisons with the mask.
92 define double @f6(i8 *%src, double %a, double %b) {
94 ; CHECK: tm 0(%r2), 254
97 %byte = load i8, i8 *%src
98 %and = and i8 %byte, 254
99 %cmp = icmp eq i8 %and, 254
100 %res = select i1 %cmp, double %b, double %a
104 ; Check inequality comparisons with the mask.
105 define double @f7(i8 *%src, double %a, double %b) {
107 ; CHECK: tm 0(%r2), 254
108 ; CHECK: jno {{\.L.*}}
110 %byte = load i8, i8 *%src
111 %and = and i8 %byte, 254
112 %cmp = icmp ne i8 %and, 254
113 %res = select i1 %cmp, double %b, double %a
117 ; Check that we do not use the memory TM instruction when CC is being tested
119 define double @f8(i8 *%src, double %a, double %b) {
121 ; CHECK: llc [[REG:%r[0-5]]], 0(%r2)
122 ; CHECK: tmll [[REG]], 3
123 ; CHECK: jh {{\.L.*}}
125 %byte = load i8, i8 *%src
126 %and = and i8 %byte, 3
127 %cmp = icmp eq i8 %and, 2
128 %res = select i1 %cmp, double %b, double %a
133 define double @f9(i8 *%src, double %a, double %b) {
135 ; CHECK: llc [[REG:%r[0-5]]], 0(%r2)
136 ; CHECK: tmll [[REG]], 3
137 ; CHECK: jl {{\.L.*}}
139 %byte = load i8, i8 *%src
140 %and = and i8 %byte, 3
141 %cmp = icmp eq i8 %and, 1
142 %res = select i1 %cmp, double %b, double %a
146 ; Check the high end of the TM range.
147 define double @f10(i8 *%src, double %a, double %b) {
149 ; CHECK: tm 4095(%r2), 1
150 ; CHECK: je {{\.L.*}}
152 %ptr = getelementptr i8, i8 *%src, i64 4095
153 %byte = load i8, i8 *%ptr
154 %and = and i8 %byte, 1
155 %cmp = icmp eq i8 %and, 0
156 %res = select i1 %cmp, double %b, double %a
160 ; Check the low end of the positive TMY range.
161 define double @f11(i8 *%src, double %a, double %b) {
163 ; CHECK: tmy 4096(%r2), 1
164 ; CHECK: je {{\.L.*}}
166 %ptr = getelementptr i8, i8 *%src, i64 4096
167 %byte = load i8, i8 *%ptr
168 %and = and i8 %byte, 1
169 %cmp = icmp eq i8 %and, 0
170 %res = select i1 %cmp, double %b, double %a
174 ; Check the high end of the TMY range.
175 define double @f12(i8 *%src, double %a, double %b) {
177 ; CHECK: tmy 524287(%r2), 1
178 ; CHECK: je {{\.L.*}}
180 %ptr = getelementptr i8, i8 *%src, i64 524287
181 %byte = load i8, i8 *%ptr
182 %and = and i8 %byte, 1
183 %cmp = icmp eq i8 %and, 0
184 %res = select i1 %cmp, double %b, double %a
188 ; Check the next byte up, which needs separate address logic.
189 define double @f13(i8 *%src, double %a, double %b) {
191 ; CHECK: agfi %r2, 524288
192 ; CHECK: tm 0(%r2), 1
193 ; CHECK: je {{\.L.*}}
195 %ptr = getelementptr i8, i8 *%src, i64 524288
196 %byte = load i8, i8 *%ptr
197 %and = and i8 %byte, 1
198 %cmp = icmp eq i8 %and, 0
199 %res = select i1 %cmp, double %b, double %a
203 ; Check the low end of the TMY range.
204 define double @f14(i8 *%src, double %a, double %b) {
206 ; CHECK: tmy -524288(%r2), 1
207 ; CHECK: je {{\.L.*}}
209 %ptr = getelementptr i8, i8 *%src, i64 -524288
210 %byte = load i8, i8 *%ptr
211 %and = and i8 %byte, 1
212 %cmp = icmp eq i8 %and, 0
213 %res = select i1 %cmp, double %b, double %a
217 ; Check the next byte down, which needs separate address logic.
218 define double @f15(i8 *%src, double %a, double %b) {
220 ; CHECK: agfi %r2, -524289
221 ; CHECK: tm 0(%r2), 1
222 ; CHECK: je {{\.L.*}}
224 %ptr = getelementptr i8, i8 *%src, i64 -524289
225 %byte = load i8, i8 *%ptr
226 %and = and i8 %byte, 1
227 %cmp = icmp eq i8 %and, 0
228 %res = select i1 %cmp, double %b, double %a
232 ; Check that TM(Y) does not allow an index
233 define double @f16(i8 *%src, i64 %index, double %a, double %b) {
235 ; CHECK: tm 0({{%r[1-5]}}), 1
236 ; CHECK: je {{\.L.*}}
238 %ptr = getelementptr i8, i8 *%src, i64 %index
239 %byte = load i8, i8 *%ptr
240 %and = and i8 %byte, 1
241 %cmp = icmp eq i8 %and, 0
242 %res = select i1 %cmp, double %b, double %a