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