1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; Test 32-bit arithmetic shifts right.
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5
6; Check the low end of the SRAG range.
7define i64 @f1(i64 %a) {
8; CHECK-LABEL: f1:
9; CHECK:       # %bb.0:
10; CHECK-NEXT:    srag %r2, %r2, 1
11; CHECK-NEXT:    br %r14
12  %shift = ashr i64 %a, 1
13  ret i64 %shift
14}
15
16; Check the high end of the defined SRAG range.
17define i64 @f2(i64 %a) {
18; CHECK-LABEL: f2:
19; CHECK:       # %bb.0:
20; CHECK-NEXT:    srag %r2, %r2, 63
21; CHECK-NEXT:    br %r14
22  %shift = ashr i64 %a, 63
23  ret i64 %shift
24}
25
26; We don't generate shifts by out-of-range values.
27define i64 @f3(i64 %a) {
28; CHECK-LABEL: f3:
29; CHECK:       # %bb.0:
30; CHECK-NEXT:    br %r14
31  %shift = ashr i64 %a, 64
32  ret i64 %shift
33}
34
35; Check variable shifts.
36define i64 @f4(i64 %a, i64 %amt) {
37; CHECK-LABEL: f4:
38; CHECK:       # %bb.0:
39; CHECK-NEXT:    srag %r2, %r2, 0(%r3)
40; CHECK-NEXT:    br %r14
41  %shift = ashr i64 %a, %amt
42  ret i64 %shift
43}
44
45; Check shift amounts that have a constant term.
46define i64 @f5(i64 %a, i64 %amt) {
47; CHECK-LABEL: f5:
48; CHECK:       # %bb.0:
49; CHECK-NEXT:    srag %r2, %r2, 10(%r3)
50; CHECK-NEXT:    br %r14
51  %add = add i64 %amt, 10
52  %shift = ashr i64 %a, %add
53  ret i64 %shift
54}
55
56; ...and again with a sign-extended 32-bit shift amount.
57define i64 @f6(i64 %a, i32 %amt) {
58; CHECK-LABEL: f6:
59; CHECK:       # %bb.0:
60; CHECK-NEXT:    srag %r2, %r2, 10(%r3)
61; CHECK-NEXT:    br %r14
62  %add = add i32 %amt, 10
63  %addext = sext i32 %add to i64
64  %shift = ashr i64 %a, %addext
65  ret i64 %shift
66}
67
68; ...and now with a zero-extended 32-bit shift amount.
69define i64 @f7(i64 %a, i32 %amt) {
70; CHECK-LABEL: f7:
71; CHECK:       # %bb.0:
72; CHECK-NEXT:    srag %r2, %r2, 10(%r3)
73; CHECK-NEXT:    br %r14
74  %add = add i32 %amt, 10
75  %addext = zext i32 %add to i64
76  %shift = ashr i64 %a, %addext
77  ret i64 %shift
78}
79
80; Check shift amounts that have the largest in-range constant term.  We could
81; mask the amount instead.
82define i64 @f8(i64 %a, i64 %amt) {
83; CHECK-LABEL: f8:
84; CHECK:       # %bb.0:
85; CHECK-NEXT:    srag %r2, %r2, 524287(%r3)
86; CHECK-NEXT:    br %r14
87  %add = add i64 %amt, 524287
88  %shift = ashr i64 %a, %add
89  ret i64 %shift
90}
91
92; Check the next value up, which without masking must use a separate
93; addition.
94define i64 @f9(i64 %a, i64 %amt) {
95; CHECK-LABEL: f9:
96; CHECK:       # %bb.0:
97; CHECK-NEXT:    afi %r3, 524288
98; CHECK-NEXT:    srag %r2, %r2, 0(%r3)
99; CHECK-NEXT:    br %r14
100  %add = add i64 %amt, 524288
101  %shift = ashr i64 %a, %add
102  ret i64 %shift
103}
104
105; Check cases where 1 is subtracted from the shift amount.
106define i64 @f10(i64 %a, i64 %amt) {
107; CHECK-LABEL: f10:
108; CHECK:       # %bb.0:
109; CHECK-NEXT:    srag %r2, %r2, -1(%r3)
110; CHECK-NEXT:    br %r14
111  %sub = sub i64 %amt, 1
112  %shift = ashr i64 %a, %sub
113  ret i64 %shift
114}
115
116; Check the lowest value that can be subtracted from the shift amount.
117; Again, we could mask the shift amount instead.
118define i64 @f11(i64 %a, i64 %amt) {
119; CHECK-LABEL: f11:
120; CHECK:       # %bb.0:
121; CHECK-NEXT:    srag %r2, %r2, -524288(%r3)
122; CHECK-NEXT:    br %r14
123  %sub = sub i64 %amt, 524288
124  %shift = ashr i64 %a, %sub
125  ret i64 %shift
126}
127
128; Check the next value down, which without masking must use a separate
129; addition.
130define i64 @f12(i64 %a, i64 %amt) {
131; CHECK-LABEL: f12:
132; CHECK:       # %bb.0:
133; CHECK-NEXT:    afi %r3, -524289
134; CHECK-NEXT:    srag %r2, %r2, 0(%r3)
135; CHECK-NEXT:    br %r14
136  %sub = sub i64 %amt, 524289
137  %shift = ashr i64 %a, %sub
138  ret i64 %shift
139}
140
141; Check that we don't try to generate "indexed" shifts.
142define i64 @f13(i64 %a, i64 %b, i64 %c) {
143; CHECK-LABEL: f13:
144; CHECK:       # %bb.0:
145; CHECK-NEXT:    agr %r3, %r4
146; CHECK-NEXT:    srag %r2, %r2, 0(%r3)
147; CHECK-NEXT:    br %r14
148  %add = add i64 %b, %c
149  %shift = ashr i64 %a, %add
150  ret i64 %shift
151}
152
153; Check that the shift amount uses an address register.  It cannot be in %r0.
154define i64 @f14(i64 %a, i64 *%ptr) {
155; CHECK-LABEL: f14:
156; CHECK:       # %bb.0:
157; CHECK-NEXT:    l %r1, 4(%r3)
158; CHECK-NEXT:    srag %r2, %r2, 0(%r1)
159; CHECK-NEXT:    br %r14
160  %amt = load i64, i64 *%ptr
161  %shift = ashr i64 %a, %amt
162  ret i64 %shift
163}
164