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