xref: /llvm-project/llvm/test/CodeGen/RISCV/avgfloors.ll (revision 9122c5235ec85ce0c0ad337e862b006e7b349d84)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s | FileCheck -check-prefix=RV32I %s
3; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s | FileCheck -check-prefix=RV64I %s
4
5;
6; fixed avg(x,y) = add(and(x,y),ashr(xor(x,y),1))
7;
8; ext avg(x,y) = trunc(ashr(add(sext(x),sext(y)),1))
9;
10
11define i8 @test_fixed_i8(i8 %a0, i8 %a1) nounwind {
12; RV32I-LABEL: test_fixed_i8:
13; RV32I:       # %bb.0:
14; RV32I-NEXT:    slli a1, a1, 24
15; RV32I-NEXT:    slli a0, a0, 24
16; RV32I-NEXT:    srai a1, a1, 24
17; RV32I-NEXT:    srai a0, a0, 24
18; RV32I-NEXT:    add a0, a0, a1
19; RV32I-NEXT:    srai a0, a0, 1
20; RV32I-NEXT:    ret
21;
22; RV64I-LABEL: test_fixed_i8:
23; RV64I:       # %bb.0:
24; RV64I-NEXT:    slli a1, a1, 56
25; RV64I-NEXT:    slli a0, a0, 56
26; RV64I-NEXT:    srai a1, a1, 56
27; RV64I-NEXT:    srai a0, a0, 56
28; RV64I-NEXT:    add a0, a0, a1
29; RV64I-NEXT:    srai a0, a0, 1
30; RV64I-NEXT:    ret
31  %and = and i8 %a0, %a1
32  %xor = xor i8 %a0, %a1
33  %shift = ashr i8 %xor, 1
34  %res = add i8 %and, %shift
35  ret i8 %res
36}
37
38define i8 @test_ext_i8(i8 %a0, i8 %a1) nounwind {
39; RV32I-LABEL: test_ext_i8:
40; RV32I:       # %bb.0:
41; RV32I-NEXT:    slli a1, a1, 24
42; RV32I-NEXT:    slli a0, a0, 24
43; RV32I-NEXT:    srai a1, a1, 24
44; RV32I-NEXT:    srai a0, a0, 24
45; RV32I-NEXT:    add a0, a0, a1
46; RV32I-NEXT:    srai a0, a0, 1
47; RV32I-NEXT:    ret
48;
49; RV64I-LABEL: test_ext_i8:
50; RV64I:       # %bb.0:
51; RV64I-NEXT:    slli a1, a1, 56
52; RV64I-NEXT:    slli a0, a0, 56
53; RV64I-NEXT:    srai a1, a1, 56
54; RV64I-NEXT:    srai a0, a0, 56
55; RV64I-NEXT:    add a0, a0, a1
56; RV64I-NEXT:    srai a0, a0, 1
57; RV64I-NEXT:    ret
58  %x0 = sext i8 %a0 to i16
59  %x1 = sext i8 %a1 to i16
60  %sum = add i16 %x0, %x1
61  %shift = ashr i16 %sum, 1
62  %res = trunc i16 %shift to i8
63  ret i8 %res
64}
65
66define i16 @test_fixed_i16(i16 %a0, i16 %a1) nounwind {
67; RV32I-LABEL: test_fixed_i16:
68; RV32I:       # %bb.0:
69; RV32I-NEXT:    slli a1, a1, 16
70; RV32I-NEXT:    slli a0, a0, 16
71; RV32I-NEXT:    srai a1, a1, 16
72; RV32I-NEXT:    srai a0, a0, 16
73; RV32I-NEXT:    add a0, a0, a1
74; RV32I-NEXT:    srai a0, a0, 1
75; RV32I-NEXT:    ret
76;
77; RV64I-LABEL: test_fixed_i16:
78; RV64I:       # %bb.0:
79; RV64I-NEXT:    slli a1, a1, 48
80; RV64I-NEXT:    slli a0, a0, 48
81; RV64I-NEXT:    srai a1, a1, 48
82; RV64I-NEXT:    srai a0, a0, 48
83; RV64I-NEXT:    add a0, a0, a1
84; RV64I-NEXT:    srai a0, a0, 1
85; RV64I-NEXT:    ret
86  %and = and i16 %a0, %a1
87  %xor = xor i16 %a0, %a1
88  %shift = ashr i16 %xor, 1
89  %res = add i16 %and, %shift
90  ret i16 %res
91}
92
93define i16 @test_ext_i16(i16 %a0, i16 %a1) nounwind {
94; RV32I-LABEL: test_ext_i16:
95; RV32I:       # %bb.0:
96; RV32I-NEXT:    slli a1, a1, 16
97; RV32I-NEXT:    slli a0, a0, 16
98; RV32I-NEXT:    srai a1, a1, 16
99; RV32I-NEXT:    srai a0, a0, 16
100; RV32I-NEXT:    add a0, a0, a1
101; RV32I-NEXT:    srai a0, a0, 1
102; RV32I-NEXT:    ret
103;
104; RV64I-LABEL: test_ext_i16:
105; RV64I:       # %bb.0:
106; RV64I-NEXT:    slli a1, a1, 48
107; RV64I-NEXT:    slli a0, a0, 48
108; RV64I-NEXT:    srai a1, a1, 48
109; RV64I-NEXT:    srai a0, a0, 48
110; RV64I-NEXT:    add a0, a0, a1
111; RV64I-NEXT:    srai a0, a0, 1
112; RV64I-NEXT:    ret
113  %x0 = sext i16 %a0 to i32
114  %x1 = sext i16 %a1 to i32
115  %sum = add i32 %x0, %x1
116  %shift = ashr i32 %sum, 1
117  %res = trunc i32 %shift to i16
118  ret i16 %res
119}
120
121define i32 @test_fixed_i32(i32 %a0, i32 %a1) nounwind {
122; RV32I-LABEL: test_fixed_i32:
123; RV32I:       # %bb.0:
124; RV32I-NEXT:    and a2, a0, a1
125; RV32I-NEXT:    xor a0, a0, a1
126; RV32I-NEXT:    srai a0, a0, 1
127; RV32I-NEXT:    add a0, a2, a0
128; RV32I-NEXT:    ret
129;
130; RV64I-LABEL: test_fixed_i32:
131; RV64I:       # %bb.0:
132; RV64I-NEXT:    sext.w a1, a1
133; RV64I-NEXT:    sext.w a0, a0
134; RV64I-NEXT:    add a0, a0, a1
135; RV64I-NEXT:    srai a0, a0, 1
136; RV64I-NEXT:    ret
137  %and = and i32 %a0, %a1
138  %xor = xor i32 %a1, %a0
139  %shift = ashr i32 %xor, 1
140  %res = add i32 %and, %shift
141  ret i32 %res
142}
143
144define i32 @test_ext_i32(i32 %a0, i32 %a1) nounwind {
145; RV32I-LABEL: test_ext_i32:
146; RV32I:       # %bb.0:
147; RV32I-NEXT:    and a2, a0, a1
148; RV32I-NEXT:    xor a0, a0, a1
149; RV32I-NEXT:    srai a0, a0, 1
150; RV32I-NEXT:    add a0, a2, a0
151; RV32I-NEXT:    ret
152;
153; RV64I-LABEL: test_ext_i32:
154; RV64I:       # %bb.0:
155; RV64I-NEXT:    sext.w a1, a1
156; RV64I-NEXT:    sext.w a0, a0
157; RV64I-NEXT:    add a0, a0, a1
158; RV64I-NEXT:    srai a0, a0, 1
159; RV64I-NEXT:    ret
160  %x0 = sext i32 %a0 to i64
161  %x1 = sext i32 %a1 to i64
162  %sum = add i64 %x0, %x1
163  %shift = ashr i64 %sum, 1
164  %res = trunc i64 %shift to i32
165  ret i32 %res
166}
167
168define i64 @test_fixed_i64(i64 %a0, i64 %a1) nounwind {
169; RV32I-LABEL: test_fixed_i64:
170; RV32I:       # %bb.0:
171; RV32I-NEXT:    and a4, a1, a3
172; RV32I-NEXT:    xor a1, a1, a3
173; RV32I-NEXT:    srai a3, a1, 1
174; RV32I-NEXT:    add a3, a4, a3
175; RV32I-NEXT:    xor a4, a0, a2
176; RV32I-NEXT:    slli a1, a1, 31
177; RV32I-NEXT:    srli a4, a4, 1
178; RV32I-NEXT:    or a1, a4, a1
179; RV32I-NEXT:    and a2, a0, a2
180; RV32I-NEXT:    add a0, a2, a1
181; RV32I-NEXT:    sltu a1, a0, a2
182; RV32I-NEXT:    add a1, a3, a1
183; RV32I-NEXT:    ret
184;
185; RV64I-LABEL: test_fixed_i64:
186; RV64I:       # %bb.0:
187; RV64I-NEXT:    and a2, a0, a1
188; RV64I-NEXT:    xor a0, a0, a1
189; RV64I-NEXT:    srai a0, a0, 1
190; RV64I-NEXT:    add a0, a2, a0
191; RV64I-NEXT:    ret
192  %and = and i64 %a0, %a1
193  %xor = xor i64 %a1, %a0
194  %shift = ashr i64 %xor, 1
195  %res = add i64 %and, %shift
196  ret i64 %res
197}
198
199define i64 @test_ext_i64(i64 %a0, i64 %a1) nounwind {
200; RV32I-LABEL: test_ext_i64:
201; RV32I:       # %bb.0:
202; RV32I-NEXT:    and a4, a1, a3
203; RV32I-NEXT:    xor a1, a1, a3
204; RV32I-NEXT:    srai a3, a1, 1
205; RV32I-NEXT:    add a3, a4, a3
206; RV32I-NEXT:    xor a4, a0, a2
207; RV32I-NEXT:    slli a1, a1, 31
208; RV32I-NEXT:    srli a4, a4, 1
209; RV32I-NEXT:    or a1, a4, a1
210; RV32I-NEXT:    and a2, a0, a2
211; RV32I-NEXT:    add a0, a2, a1
212; RV32I-NEXT:    sltu a1, a0, a2
213; RV32I-NEXT:    add a1, a3, a1
214; RV32I-NEXT:    ret
215;
216; RV64I-LABEL: test_ext_i64:
217; RV64I:       # %bb.0:
218; RV64I-NEXT:    and a2, a0, a1
219; RV64I-NEXT:    xor a0, a0, a1
220; RV64I-NEXT:    srai a0, a0, 1
221; RV64I-NEXT:    add a0, a2, a0
222; RV64I-NEXT:    ret
223  %x0 = sext i64 %a0 to i128
224  %x1 = sext i64 %a1 to i128
225  %sum = add i128 %x0, %x1
226  %shift = ashr i128 %sum, 1
227  %res = trunc i128 %shift to i64
228  ret i64 %res
229}
230