xref: /llvm-project/llvm/test/CodeGen/RISCV/uadd_sat_plus.ll (revision 9122c5235ec85ce0c0ad337e862b006e7b349d84)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=riscv32 -mattr=+m | FileCheck %s --check-prefix=RV32I
3; RUN: llc < %s -mtriple=riscv64 -mattr=+m | FileCheck %s --check-prefix=RV64I
4; RUN: llc < %s -mtriple=riscv32 -mattr=+m,+zbb | FileCheck %s --check-prefix=RV32IZbb
5; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zbb | FileCheck %s --check-prefix=RV64IZbb
6
7declare i4 @llvm.uadd.sat.i4(i4, i4)
8declare i8 @llvm.uadd.sat.i8(i8, i8)
9declare i16 @llvm.uadd.sat.i16(i16, i16)
10declare i32 @llvm.uadd.sat.i32(i32, i32)
11declare i64 @llvm.uadd.sat.i64(i64, i64)
12
13define i32 @func32(i32 %x, i32 %y, i32 %z) nounwind {
14; RV32I-LABEL: func32:
15; RV32I:       # %bb.0:
16; RV32I-NEXT:    mul a1, a1, a2
17; RV32I-NEXT:    add a1, a0, a1
18; RV32I-NEXT:    sltu a0, a1, a0
19; RV32I-NEXT:    neg a0, a0
20; RV32I-NEXT:    or a0, a0, a1
21; RV32I-NEXT:    ret
22;
23; RV64I-LABEL: func32:
24; RV64I:       # %bb.0:
25; RV64I-NEXT:    mul a1, a1, a2
26; RV64I-NEXT:    addw a1, a0, a1
27; RV64I-NEXT:    sext.w a0, a0
28; RV64I-NEXT:    sltu a0, a1, a0
29; RV64I-NEXT:    neg a0, a0
30; RV64I-NEXT:    or a0, a0, a1
31; RV64I-NEXT:    ret
32;
33; RV32IZbb-LABEL: func32:
34; RV32IZbb:       # %bb.0:
35; RV32IZbb-NEXT:    mul a1, a1, a2
36; RV32IZbb-NEXT:    not a2, a1
37; RV32IZbb-NEXT:    minu a0, a0, a2
38; RV32IZbb-NEXT:    add a0, a0, a1
39; RV32IZbb-NEXT:    ret
40;
41; RV64IZbb-LABEL: func32:
42; RV64IZbb:       # %bb.0:
43; RV64IZbb-NEXT:    sext.w a0, a0
44; RV64IZbb-NEXT:    mulw a1, a1, a2
45; RV64IZbb-NEXT:    not a2, a1
46; RV64IZbb-NEXT:    minu a0, a0, a2
47; RV64IZbb-NEXT:    add a0, a0, a1
48; RV64IZbb-NEXT:    ret
49  %a = mul i32 %y, %z
50  %tmp = call i32 @llvm.uadd.sat.i32(i32 %x, i32 %a)
51  ret i32 %tmp
52}
53
54define i64 @func64(i64 %x, i64 %y, i64 %z) nounwind {
55; RV32I-LABEL: func64:
56; RV32I:       # %bb.0:
57; RV32I-NEXT:    add a2, a1, a5
58; RV32I-NEXT:    add a4, a0, a4
59; RV32I-NEXT:    sltu a0, a4, a0
60; RV32I-NEXT:    add a2, a2, a0
61; RV32I-NEXT:    beq a2, a1, .LBB1_2
62; RV32I-NEXT:  # %bb.1:
63; RV32I-NEXT:    sltu a0, a2, a1
64; RV32I-NEXT:  .LBB1_2:
65; RV32I-NEXT:    neg a1, a0
66; RV32I-NEXT:    or a0, a1, a4
67; RV32I-NEXT:    or a1, a1, a2
68; RV32I-NEXT:    ret
69;
70; RV64I-LABEL: func64:
71; RV64I:       # %bb.0:
72; RV64I-NEXT:    add a2, a0, a2
73; RV64I-NEXT:    sltu a0, a2, a0
74; RV64I-NEXT:    neg a0, a0
75; RV64I-NEXT:    or a0, a0, a2
76; RV64I-NEXT:    ret
77;
78; RV32IZbb-LABEL: func64:
79; RV32IZbb:       # %bb.0:
80; RV32IZbb-NEXT:    add a2, a1, a5
81; RV32IZbb-NEXT:    add a4, a0, a4
82; RV32IZbb-NEXT:    sltu a0, a4, a0
83; RV32IZbb-NEXT:    add a2, a2, a0
84; RV32IZbb-NEXT:    beq a2, a1, .LBB1_2
85; RV32IZbb-NEXT:  # %bb.1:
86; RV32IZbb-NEXT:    sltu a0, a2, a1
87; RV32IZbb-NEXT:  .LBB1_2:
88; RV32IZbb-NEXT:    neg a1, a0
89; RV32IZbb-NEXT:    or a0, a1, a4
90; RV32IZbb-NEXT:    or a1, a1, a2
91; RV32IZbb-NEXT:    ret
92;
93; RV64IZbb-LABEL: func64:
94; RV64IZbb:       # %bb.0:
95; RV64IZbb-NEXT:    not a1, a2
96; RV64IZbb-NEXT:    minu a0, a0, a1
97; RV64IZbb-NEXT:    add a0, a0, a2
98; RV64IZbb-NEXT:    ret
99  %a = mul i64 %y, %z
100  %tmp = call i64 @llvm.uadd.sat.i64(i64 %x, i64 %z)
101  ret i64 %tmp
102}
103
104define i16 @func16(i16 %x, i16 %y, i16 %z) nounwind {
105; RV32I-LABEL: func16:
106; RV32I:       # %bb.0:
107; RV32I-NEXT:    lui a3, 16
108; RV32I-NEXT:    mul a2, a1, a2
109; RV32I-NEXT:    addi a1, a3, -1
110; RV32I-NEXT:    and a0, a0, a1
111; RV32I-NEXT:    and a2, a2, a1
112; RV32I-NEXT:    add a0, a0, a2
113; RV32I-NEXT:    bltu a0, a1, .LBB2_2
114; RV32I-NEXT:  # %bb.1:
115; RV32I-NEXT:    mv a0, a1
116; RV32I-NEXT:  .LBB2_2:
117; RV32I-NEXT:    ret
118;
119; RV64I-LABEL: func16:
120; RV64I:       # %bb.0:
121; RV64I-NEXT:    lui a3, 16
122; RV64I-NEXT:    mul a2, a1, a2
123; RV64I-NEXT:    addiw a1, a3, -1
124; RV64I-NEXT:    and a0, a0, a1
125; RV64I-NEXT:    and a2, a2, a1
126; RV64I-NEXT:    add a0, a0, a2
127; RV64I-NEXT:    bltu a0, a1, .LBB2_2
128; RV64I-NEXT:  # %bb.1:
129; RV64I-NEXT:    mv a0, a1
130; RV64I-NEXT:  .LBB2_2:
131; RV64I-NEXT:    ret
132;
133; RV32IZbb-LABEL: func16:
134; RV32IZbb:       # %bb.0:
135; RV32IZbb-NEXT:    zext.h a0, a0
136; RV32IZbb-NEXT:    mul a1, a1, a2
137; RV32IZbb-NEXT:    lui a2, 16
138; RV32IZbb-NEXT:    zext.h a1, a1
139; RV32IZbb-NEXT:    add a0, a0, a1
140; RV32IZbb-NEXT:    addi a2, a2, -1
141; RV32IZbb-NEXT:    minu a0, a0, a2
142; RV32IZbb-NEXT:    ret
143;
144; RV64IZbb-LABEL: func16:
145; RV64IZbb:       # %bb.0:
146; RV64IZbb-NEXT:    zext.h a0, a0
147; RV64IZbb-NEXT:    mul a1, a1, a2
148; RV64IZbb-NEXT:    lui a2, 16
149; RV64IZbb-NEXT:    zext.h a1, a1
150; RV64IZbb-NEXT:    add a0, a0, a1
151; RV64IZbb-NEXT:    addiw a2, a2, -1
152; RV64IZbb-NEXT:    minu a0, a0, a2
153; RV64IZbb-NEXT:    ret
154  %a = mul i16 %y, %z
155  %tmp = call i16 @llvm.uadd.sat.i16(i16 %x, i16 %a)
156  ret i16 %tmp
157}
158
159define i8 @func8(i8 %x, i8 %y, i8 %z) nounwind {
160; RV32I-LABEL: func8:
161; RV32I:       # %bb.0:
162; RV32I-NEXT:    andi a0, a0, 255
163; RV32I-NEXT:    mul a1, a1, a2
164; RV32I-NEXT:    andi a1, a1, 255
165; RV32I-NEXT:    add a0, a0, a1
166; RV32I-NEXT:    li a1, 255
167; RV32I-NEXT:    bltu a0, a1, .LBB3_2
168; RV32I-NEXT:  # %bb.1:
169; RV32I-NEXT:    li a0, 255
170; RV32I-NEXT:  .LBB3_2:
171; RV32I-NEXT:    ret
172;
173; RV64I-LABEL: func8:
174; RV64I:       # %bb.0:
175; RV64I-NEXT:    andi a0, a0, 255
176; RV64I-NEXT:    mul a1, a1, a2
177; RV64I-NEXT:    andi a1, a1, 255
178; RV64I-NEXT:    add a0, a0, a1
179; RV64I-NEXT:    li a1, 255
180; RV64I-NEXT:    bltu a0, a1, .LBB3_2
181; RV64I-NEXT:  # %bb.1:
182; RV64I-NEXT:    li a0, 255
183; RV64I-NEXT:  .LBB3_2:
184; RV64I-NEXT:    ret
185;
186; RV32IZbb-LABEL: func8:
187; RV32IZbb:       # %bb.0:
188; RV32IZbb-NEXT:    andi a0, a0, 255
189; RV32IZbb-NEXT:    mul a1, a1, a2
190; RV32IZbb-NEXT:    andi a1, a1, 255
191; RV32IZbb-NEXT:    add a0, a0, a1
192; RV32IZbb-NEXT:    li a1, 255
193; RV32IZbb-NEXT:    minu a0, a0, a1
194; RV32IZbb-NEXT:    ret
195;
196; RV64IZbb-LABEL: func8:
197; RV64IZbb:       # %bb.0:
198; RV64IZbb-NEXT:    andi a0, a0, 255
199; RV64IZbb-NEXT:    mul a1, a1, a2
200; RV64IZbb-NEXT:    andi a1, a1, 255
201; RV64IZbb-NEXT:    add a0, a0, a1
202; RV64IZbb-NEXT:    li a1, 255
203; RV64IZbb-NEXT:    minu a0, a0, a1
204; RV64IZbb-NEXT:    ret
205  %a = mul i8 %y, %z
206  %tmp = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %a)
207  ret i8 %tmp
208}
209
210define i4 @func4(i4 %x, i4 %y, i4 %z) nounwind {
211; RV32I-LABEL: func4:
212; RV32I:       # %bb.0:
213; RV32I-NEXT:    andi a0, a0, 15
214; RV32I-NEXT:    mul a1, a1, a2
215; RV32I-NEXT:    andi a1, a1, 15
216; RV32I-NEXT:    add a0, a0, a1
217; RV32I-NEXT:    li a1, 15
218; RV32I-NEXT:    bltu a0, a1, .LBB4_2
219; RV32I-NEXT:  # %bb.1:
220; RV32I-NEXT:    li a0, 15
221; RV32I-NEXT:  .LBB4_2:
222; RV32I-NEXT:    ret
223;
224; RV64I-LABEL: func4:
225; RV64I:       # %bb.0:
226; RV64I-NEXT:    andi a0, a0, 15
227; RV64I-NEXT:    mul a1, a1, a2
228; RV64I-NEXT:    andi a1, a1, 15
229; RV64I-NEXT:    add a0, a0, a1
230; RV64I-NEXT:    li a1, 15
231; RV64I-NEXT:    bltu a0, a1, .LBB4_2
232; RV64I-NEXT:  # %bb.1:
233; RV64I-NEXT:    li a0, 15
234; RV64I-NEXT:  .LBB4_2:
235; RV64I-NEXT:    ret
236;
237; RV32IZbb-LABEL: func4:
238; RV32IZbb:       # %bb.0:
239; RV32IZbb-NEXT:    andi a0, a0, 15
240; RV32IZbb-NEXT:    mul a1, a1, a2
241; RV32IZbb-NEXT:    andi a1, a1, 15
242; RV32IZbb-NEXT:    add a0, a0, a1
243; RV32IZbb-NEXT:    li a1, 15
244; RV32IZbb-NEXT:    minu a0, a0, a1
245; RV32IZbb-NEXT:    ret
246;
247; RV64IZbb-LABEL: func4:
248; RV64IZbb:       # %bb.0:
249; RV64IZbb-NEXT:    andi a0, a0, 15
250; RV64IZbb-NEXT:    mul a1, a1, a2
251; RV64IZbb-NEXT:    andi a1, a1, 15
252; RV64IZbb-NEXT:    add a0, a0, a1
253; RV64IZbb-NEXT:    li a1, 15
254; RV64IZbb-NEXT:    minu a0, a0, a1
255; RV64IZbb-NEXT:    ret
256  %a = mul i4 %y, %z
257  %tmp = call i4 @llvm.uadd.sat.i4(i4 %x, i4 %a)
258  ret i4 %tmp
259}
260