1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; Test removal of AND operations that don't affect last 6 bits of shift amount
3; operand.
4;
5; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
6
7; Test that AND is not removed when some lower 6 bits are not set.
8define i32 @f1(i32 %a, i32 %sh) {
9; CHECK-LABEL: f1:
10; CHECK:       # %bb.0:
11; CHECK-NEXT:    nill %r3, 31
12; CHECK-NEXT:    sll %r2, 0(%r3)
13; CHECK-NEXT:    br %r14
14  %and = and i32 %sh, 31
15  %shift = shl i32 %a, %and
16  ret i32 %shift
17}
18
19; Test removal of AND mask with only bottom 6 bits set.
20define i32 @f2(i32 %a, i32 %sh) {
21; CHECK-LABEL: f2:
22; CHECK:       # %bb.0:
23; CHECK-NEXT:    sll %r2, 0(%r3)
24; CHECK-NEXT:    br %r14
25  %and = and i32 %sh, 63
26  %shift = shl i32 %a, %and
27  ret i32 %shift
28}
29
30; Test removal of AND mask including but not limited to bottom 6 bits.
31define i32 @f3(i32 %a, i32 %sh) {
32; CHECK-LABEL: f3:
33; CHECK:       # %bb.0:
34; CHECK-NEXT:    sll %r2, 0(%r3)
35; CHECK-NEXT:    br %r14
36  %and = and i32 %sh, 255
37  %shift = shl i32 %a, %and
38  ret i32 %shift
39}
40
41; Test removal of AND mask from SRA.
42define i32 @f4(i32 %a, i32 %sh) {
43; CHECK-LABEL: f4:
44; CHECK:       # %bb.0:
45; CHECK-NEXT:    sra %r2, 0(%r3)
46; CHECK-NEXT:    br %r14
47  %and = and i32 %sh, 63
48  %shift = ashr i32 %a, %and
49  ret i32 %shift
50}
51
52; Test removal of AND mask from SRL.
53define i32 @f5(i32 %a, i32 %sh) {
54; CHECK-LABEL: f5:
55; CHECK:       # %bb.0:
56; CHECK-NEXT:    srl %r2, 0(%r3)
57; CHECK-NEXT:    br %r14
58  %and = and i32 %sh, 63
59  %shift = lshr i32 %a, %and
60  ret i32 %shift
61}
62
63; Test removal of AND mask from SLLG.
64define i64 @f6(i64 %a, i64 %sh) {
65; CHECK-LABEL: f6:
66; CHECK:       # %bb.0:
67; CHECK-NEXT:    sllg %r2, %r2, 0(%r3)
68; CHECK-NEXT:    br %r14
69  %and = and i64 %sh, 63
70  %shift = shl i64 %a, %and
71  ret i64 %shift
72}
73
74; Test removal of AND mask from SRAG.
75define i64 @f7(i64 %a, i64 %sh) {
76; CHECK-LABEL: f7:
77; CHECK:       # %bb.0:
78; CHECK-NEXT:    srag %r2, %r2, 0(%r3)
79; CHECK-NEXT:    br %r14
80  %and = and i64 %sh, 63
81  %shift = ashr i64 %a, %and
82  ret i64 %shift
83}
84
85; Test removal of AND mask from SRLG.
86define i64 @f8(i64 %a, i64 %sh) {
87; CHECK-LABEL: f8:
88; CHECK:       # %bb.0:
89; CHECK-NEXT:    srlg %r2, %r2, 0(%r3)
90; CHECK-NEXT:    br %r14
91  %and = and i64 %sh, 63
92  %shift = lshr i64 %a, %and
93  ret i64 %shift
94}
95
96; Test that AND with two register operands is not affected.
97define i32 @f9(i32 %a, i32 %b, i32 %sh) {
98; CHECK-LABEL: f9:
99; CHECK:       # %bb.0:
100; CHECK-NEXT:    nr %r3, %r4
101; CHECK-NEXT:    sll %r2, 0(%r3)
102; CHECK-NEXT:    br %r14
103  %and = and i32 %sh, %b
104  %shift = shl i32 %a, %and
105  ret i32 %shift
106}
107
108; Test that AND is not entirely removed if the result is reused.
109define i32 @f10(i32 %a, i32 %sh) {
110; CHECK-LABEL: f10:
111; CHECK:       # %bb.0:
112; CHECK-NEXT:    sll %r2, 0(%r3)
113; CHECK-NEXT:    nilf %r3, 63
114; CHECK-NEXT:    ar %r2, %r3
115; CHECK-NEXT:    br %r14
116  %and = and i32 %sh, 63
117  %shift = shl i32 %a, %and
118  %reuse = add i32 %and, %shift
119  ret i32 %reuse
120}
121
122define i128 @f11(i128 %a, i32 %sh) {
123; CHECK-LABEL: f11:
124; CHECK:       # %bb.0:
125; CHECK-NEXT:    stmg %r14, %r15, 112(%r15)
126; CHECK-NEXT:    .cfi_offset %r14, -48
127; CHECK-NEXT:    .cfi_offset %r15, -40
128; CHECK-NEXT:    lg %r0, 8(%r3)
129; CHECK-NEXT:    lg %r1, 0(%r3)
130; CHECK-NEXT:    risblg %r3, %r4, 25, 159, 0
131; CHECK-NEXT:    lcr %r14, %r3
132; CHECK-NEXT:    sllg %r5, %r1, 0(%r4)
133; CHECK-NEXT:    srlg %r14, %r0, 0(%r14)
134; CHECK-NEXT:    ogr %r5, %r14
135; CHECK-NEXT:    sllg %r3, %r0, -64(%r3)
136; CHECK-NEXT:    tmll %r4, 127
137; CHECK-NEXT:    locgrle %r3, %r5
138; CHECK-NEXT:    sllg %r0, %r0, 0(%r4)
139; CHECK-NEXT:    locgre %r3, %r1
140; CHECK-NEXT:    locghinle %r0, 0
141; CHECK-NEXT:    stg %r0, 8(%r2)
142; CHECK-NEXT:    stg %r3, 0(%r2)
143; CHECK-NEXT:    lmg %r14, %r15, 112(%r15)
144; CHECK-NEXT:    br %r14
145  %and = and i32 %sh, 127
146  %ext = zext i32 %and to i128
147  %shift = shl i128 %a, %ext
148  ret i128 %shift
149}
150
151define i128 @f12(i128 %a, i32 %sh) {
152; CHECK-LABEL: f12:
153; CHECK:       # %bb.0:
154; CHECK-NEXT:    stmg %r14, %r15, 112(%r15)
155; CHECK-NEXT:    .cfi_offset %r14, -48
156; CHECK-NEXT:    .cfi_offset %r15, -40
157; CHECK-NEXT:    lg %r0, 0(%r3)
158; CHECK-NEXT:    lg %r1, 8(%r3)
159; CHECK-NEXT:    risblg %r3, %r4, 25, 159, 0
160; CHECK-NEXT:    lcr %r14, %r3
161; CHECK-NEXT:    srlg %r5, %r1, 0(%r4)
162; CHECK-NEXT:    sllg %r14, %r0, 0(%r14)
163; CHECK-NEXT:    ogr %r5, %r14
164; CHECK-NEXT:    srlg %r3, %r0, -64(%r3)
165; CHECK-NEXT:    tmll %r4, 127
166; CHECK-NEXT:    locgrle %r3, %r5
167; CHECK-NEXT:    srlg %r0, %r0, 0(%r4)
168; CHECK-NEXT:    locgre %r3, %r1
169; CHECK-NEXT:    locghinle %r0, 0
170; CHECK-NEXT:    stg %r0, 0(%r2)
171; CHECK-NEXT:    stg %r3, 8(%r2)
172; CHECK-NEXT:    lmg %r14, %r15, 112(%r15)
173; CHECK-NEXT:    br %r14
174  %and = and i32 %sh, 127
175  %ext = zext i32 %and to i128
176  %shift = lshr i128 %a, %ext
177  ret i128 %shift
178}
179
180define i128 @f13(i128 %a, i32 %sh) {
181; CHECK-LABEL: f13:
182; CHECK:       # %bb.0:
183; CHECK-NEXT:    stmg %r14, %r15, 112(%r15)
184; CHECK-NEXT:    .cfi_offset %r14, -48
185; CHECK-NEXT:    .cfi_offset %r15, -40
186; CHECK-NEXT:    lg %r0, 0(%r3)
187; CHECK-NEXT:    lg %r1, 8(%r3)
188; CHECK-NEXT:    risblg %r3, %r4, 25, 159, 0
189; CHECK-NEXT:    lcr %r14, %r3
190; CHECK-NEXT:    srlg %r5, %r1, 0(%r4)
191; CHECK-NEXT:    sllg %r14, %r0, 0(%r14)
192; CHECK-NEXT:    ogr %r5, %r14
193; CHECK-NEXT:    srag %r14, %r0, 0(%r4)
194; CHECK-NEXT:    srag %r3, %r0, -64(%r3)
195; CHECK-NEXT:    srag %r0, %r0, 63
196; CHECK-NEXT:    tmll %r4, 127
197; CHECK-NEXT:    locgrle %r3, %r5
198; CHECK-NEXT:    locgre %r3, %r1
199; CHECK-NEXT:    locgrle %r0, %r14
200; CHECK-NEXT:    stg %r0, 0(%r2)
201; CHECK-NEXT:    stg %r3, 8(%r2)
202; CHECK-NEXT:    lmg %r14, %r15, 112(%r15)
203; CHECK-NEXT:    br %r14
204  %and = and i32 %sh, 127
205  %ext = zext i32 %and to i128
206  %shift = ashr i128 %a, %ext
207  ret i128 %shift
208}
209
210