xref: /llvm-project/llvm/test/CodeGen/RISCV/sadd_sat.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-prefixes=RV32,RV32I
3; RUN: llc < %s -mtriple=riscv64 -mattr=+m | FileCheck %s --check-prefixes=RV64,RV64I
4; RUN: llc < %s -mtriple=riscv32 -mattr=+m,+zbb | FileCheck %s --check-prefixes=RV32,RV32IZbb
5; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zbb | FileCheck %s --check-prefixes=RV64,RV64IZbb
6
7declare i4 @llvm.sadd.sat.i4(i4, i4)
8declare i8 @llvm.sadd.sat.i8(i8, i8)
9declare i16 @llvm.sadd.sat.i16(i16, i16)
10declare i32 @llvm.sadd.sat.i32(i32, i32)
11declare i64 @llvm.sadd.sat.i64(i64, i64)
12
13define signext i32 @func(i32 signext %x, i32 signext %y) nounwind {
14; RV32-LABEL: func:
15; RV32:       # %bb.0:
16; RV32-NEXT:    mv a2, a0
17; RV32-NEXT:    add a0, a0, a1
18; RV32-NEXT:    slt a2, a0, a2
19; RV32-NEXT:    slti a1, a1, 0
20; RV32-NEXT:    beq a1, a2, .LBB0_2
21; RV32-NEXT:  # %bb.1:
22; RV32-NEXT:    srai a0, a0, 31
23; RV32-NEXT:    lui a1, 524288
24; RV32-NEXT:    xor a0, a0, a1
25; RV32-NEXT:  .LBB0_2:
26; RV32-NEXT:    ret
27;
28; RV64I-LABEL: func:
29; RV64I:       # %bb.0:
30; RV64I-NEXT:    add a2, a0, a1
31; RV64I-NEXT:    addw a0, a0, a1
32; RV64I-NEXT:    beq a0, a2, .LBB0_2
33; RV64I-NEXT:  # %bb.1:
34; RV64I-NEXT:    srli a0, a0, 31
35; RV64I-NEXT:    li a1, 1
36; RV64I-NEXT:    slli a1, a1, 31
37; RV64I-NEXT:    xor a2, a0, a1
38; RV64I-NEXT:  .LBB0_2:
39; RV64I-NEXT:    sext.w a0, a2
40; RV64I-NEXT:    ret
41;
42; RV64IZbb-LABEL: func:
43; RV64IZbb:       # %bb.0:
44; RV64IZbb-NEXT:    add a0, a0, a1
45; RV64IZbb-NEXT:    lui a1, 524288
46; RV64IZbb-NEXT:    addiw a2, a1, -1
47; RV64IZbb-NEXT:    min a0, a0, a2
48; RV64IZbb-NEXT:    max a0, a0, a1
49; RV64IZbb-NEXT:    ret
50  %tmp = call i32 @llvm.sadd.sat.i32(i32 %x, i32 %y);
51  ret i32 %tmp;
52}
53
54define i64 @func2(i64 %x, i64 %y) nounwind {
55; RV32I-LABEL: func2:
56; RV32I:       # %bb.0:
57; RV32I-NEXT:    mv a4, a1
58; RV32I-NEXT:    mv a1, a0
59; RV32I-NEXT:    add a5, a4, a3
60; RV32I-NEXT:    add a0, a0, a2
61; RV32I-NEXT:    xor a3, a4, a3
62; RV32I-NEXT:    sltu a1, a0, a1
63; RV32I-NEXT:    add a1, a5, a1
64; RV32I-NEXT:    xor a4, a4, a1
65; RV32I-NEXT:    not a2, a3
66; RV32I-NEXT:    and a2, a2, a4
67; RV32I-NEXT:    bgez a2, .LBB1_2
68; RV32I-NEXT:  # %bb.1:
69; RV32I-NEXT:    srai a0, a1, 31
70; RV32I-NEXT:    lui a1, 524288
71; RV32I-NEXT:    xor a1, a0, a1
72; RV32I-NEXT:  .LBB1_2:
73; RV32I-NEXT:    ret
74;
75; RV64-LABEL: func2:
76; RV64:       # %bb.0:
77; RV64-NEXT:    mv a2, a0
78; RV64-NEXT:    add a0, a0, a1
79; RV64-NEXT:    slt a2, a0, a2
80; RV64-NEXT:    slti a1, a1, 0
81; RV64-NEXT:    beq a1, a2, .LBB1_2
82; RV64-NEXT:  # %bb.1:
83; RV64-NEXT:    srai a0, a0, 63
84; RV64-NEXT:    li a1, -1
85; RV64-NEXT:    slli a1, a1, 63
86; RV64-NEXT:    xor a0, a0, a1
87; RV64-NEXT:  .LBB1_2:
88; RV64-NEXT:    ret
89;
90; RV32IZbb-LABEL: func2:
91; RV32IZbb:       # %bb.0:
92; RV32IZbb-NEXT:    mv a4, a1
93; RV32IZbb-NEXT:    mv a1, a0
94; RV32IZbb-NEXT:    add a5, a4, a3
95; RV32IZbb-NEXT:    add a0, a0, a2
96; RV32IZbb-NEXT:    sltu a1, a0, a1
97; RV32IZbb-NEXT:    add a1, a5, a1
98; RV32IZbb-NEXT:    xor a2, a4, a1
99; RV32IZbb-NEXT:    xor a3, a4, a3
100; RV32IZbb-NEXT:    andn a2, a2, a3
101; RV32IZbb-NEXT:    bgez a2, .LBB1_2
102; RV32IZbb-NEXT:  # %bb.1:
103; RV32IZbb-NEXT:    srai a0, a1, 31
104; RV32IZbb-NEXT:    lui a1, 524288
105; RV32IZbb-NEXT:    xor a1, a0, a1
106; RV32IZbb-NEXT:  .LBB1_2:
107; RV32IZbb-NEXT:    ret
108  %tmp = call i64 @llvm.sadd.sat.i64(i64 %x, i64 %y);
109  ret i64 %tmp;
110}
111
112define signext i16 @func16(i16 signext %x, i16 signext %y) nounwind {
113; RV32I-LABEL: func16:
114; RV32I:       # %bb.0:
115; RV32I-NEXT:    add a0, a0, a1
116; RV32I-NEXT:    lui a1, 8
117; RV32I-NEXT:    addi a1, a1, -1
118; RV32I-NEXT:    bge a0, a1, .LBB2_3
119; RV32I-NEXT:  # %bb.1:
120; RV32I-NEXT:    lui a1, 1048568
121; RV32I-NEXT:    bge a1, a0, .LBB2_4
122; RV32I-NEXT:  .LBB2_2:
123; RV32I-NEXT:    ret
124; RV32I-NEXT:  .LBB2_3:
125; RV32I-NEXT:    mv a0, a1
126; RV32I-NEXT:    lui a1, 1048568
127; RV32I-NEXT:    blt a1, a0, .LBB2_2
128; RV32I-NEXT:  .LBB2_4:
129; RV32I-NEXT:    lui a0, 1048568
130; RV32I-NEXT:    ret
131;
132; RV64I-LABEL: func16:
133; RV64I:       # %bb.0:
134; RV64I-NEXT:    add a0, a0, a1
135; RV64I-NEXT:    lui a1, 8
136; RV64I-NEXT:    addiw a1, a1, -1
137; RV64I-NEXT:    bge a0, a1, .LBB2_3
138; RV64I-NEXT:  # %bb.1:
139; RV64I-NEXT:    lui a1, 1048568
140; RV64I-NEXT:    bge a1, a0, .LBB2_4
141; RV64I-NEXT:  .LBB2_2:
142; RV64I-NEXT:    ret
143; RV64I-NEXT:  .LBB2_3:
144; RV64I-NEXT:    mv a0, a1
145; RV64I-NEXT:    lui a1, 1048568
146; RV64I-NEXT:    blt a1, a0, .LBB2_2
147; RV64I-NEXT:  .LBB2_4:
148; RV64I-NEXT:    lui a0, 1048568
149; RV64I-NEXT:    ret
150;
151; RV32IZbb-LABEL: func16:
152; RV32IZbb:       # %bb.0:
153; RV32IZbb-NEXT:    add a0, a0, a1
154; RV32IZbb-NEXT:    lui a1, 8
155; RV32IZbb-NEXT:    addi a1, a1, -1
156; RV32IZbb-NEXT:    min a0, a0, a1
157; RV32IZbb-NEXT:    lui a1, 1048568
158; RV32IZbb-NEXT:    max a0, a0, a1
159; RV32IZbb-NEXT:    ret
160;
161; RV64IZbb-LABEL: func16:
162; RV64IZbb:       # %bb.0:
163; RV64IZbb-NEXT:    add a0, a0, a1
164; RV64IZbb-NEXT:    lui a1, 8
165; RV64IZbb-NEXT:    addiw a1, a1, -1
166; RV64IZbb-NEXT:    min a0, a0, a1
167; RV64IZbb-NEXT:    lui a1, 1048568
168; RV64IZbb-NEXT:    max a0, a0, a1
169; RV64IZbb-NEXT:    ret
170  %tmp = call i16 @llvm.sadd.sat.i16(i16 %x, i16 %y);
171  ret i16 %tmp;
172}
173
174define signext i8 @func8(i8 signext %x, i8 signext %y) nounwind {
175; RV32I-LABEL: func8:
176; RV32I:       # %bb.0:
177; RV32I-NEXT:    add a0, a0, a1
178; RV32I-NEXT:    li a1, 127
179; RV32I-NEXT:    bge a0, a1, .LBB3_3
180; RV32I-NEXT:  # %bb.1:
181; RV32I-NEXT:    li a1, -128
182; RV32I-NEXT:    bge a1, a0, .LBB3_4
183; RV32I-NEXT:  .LBB3_2:
184; RV32I-NEXT:    ret
185; RV32I-NEXT:  .LBB3_3:
186; RV32I-NEXT:    li a0, 127
187; RV32I-NEXT:    li a1, -128
188; RV32I-NEXT:    blt a1, a0, .LBB3_2
189; RV32I-NEXT:  .LBB3_4:
190; RV32I-NEXT:    li a0, -128
191; RV32I-NEXT:    ret
192;
193; RV64I-LABEL: func8:
194; RV64I:       # %bb.0:
195; RV64I-NEXT:    add a0, a0, a1
196; RV64I-NEXT:    li a1, 127
197; RV64I-NEXT:    bge a0, a1, .LBB3_3
198; RV64I-NEXT:  # %bb.1:
199; RV64I-NEXT:    li a1, -128
200; RV64I-NEXT:    bge a1, a0, .LBB3_4
201; RV64I-NEXT:  .LBB3_2:
202; RV64I-NEXT:    ret
203; RV64I-NEXT:  .LBB3_3:
204; RV64I-NEXT:    li a0, 127
205; RV64I-NEXT:    li a1, -128
206; RV64I-NEXT:    blt a1, a0, .LBB3_2
207; RV64I-NEXT:  .LBB3_4:
208; RV64I-NEXT:    li a0, -128
209; RV64I-NEXT:    ret
210;
211; RV32IZbb-LABEL: func8:
212; RV32IZbb:       # %bb.0:
213; RV32IZbb-NEXT:    add a0, a0, a1
214; RV32IZbb-NEXT:    li a1, 127
215; RV32IZbb-NEXT:    min a0, a0, a1
216; RV32IZbb-NEXT:    li a1, -128
217; RV32IZbb-NEXT:    max a0, a0, a1
218; RV32IZbb-NEXT:    ret
219;
220; RV64IZbb-LABEL: func8:
221; RV64IZbb:       # %bb.0:
222; RV64IZbb-NEXT:    add a0, a0, a1
223; RV64IZbb-NEXT:    li a1, 127
224; RV64IZbb-NEXT:    min a0, a0, a1
225; RV64IZbb-NEXT:    li a1, -128
226; RV64IZbb-NEXT:    max a0, a0, a1
227; RV64IZbb-NEXT:    ret
228  %tmp = call i8 @llvm.sadd.sat.i8(i8 %x, i8 %y);
229  ret i8 %tmp;
230}
231
232define signext i4 @func3(i4 signext %x, i4 signext %y) nounwind {
233; RV32I-LABEL: func3:
234; RV32I:       # %bb.0:
235; RV32I-NEXT:    add a0, a0, a1
236; RV32I-NEXT:    li a1, 7
237; RV32I-NEXT:    bge a0, a1, .LBB4_3
238; RV32I-NEXT:  # %bb.1:
239; RV32I-NEXT:    li a1, -8
240; RV32I-NEXT:    bge a1, a0, .LBB4_4
241; RV32I-NEXT:  .LBB4_2:
242; RV32I-NEXT:    ret
243; RV32I-NEXT:  .LBB4_3:
244; RV32I-NEXT:    li a0, 7
245; RV32I-NEXT:    li a1, -8
246; RV32I-NEXT:    blt a1, a0, .LBB4_2
247; RV32I-NEXT:  .LBB4_4:
248; RV32I-NEXT:    li a0, -8
249; RV32I-NEXT:    ret
250;
251; RV64I-LABEL: func3:
252; RV64I:       # %bb.0:
253; RV64I-NEXT:    add a0, a0, a1
254; RV64I-NEXT:    li a1, 7
255; RV64I-NEXT:    bge a0, a1, .LBB4_3
256; RV64I-NEXT:  # %bb.1:
257; RV64I-NEXT:    li a1, -8
258; RV64I-NEXT:    bge a1, a0, .LBB4_4
259; RV64I-NEXT:  .LBB4_2:
260; RV64I-NEXT:    ret
261; RV64I-NEXT:  .LBB4_3:
262; RV64I-NEXT:    li a0, 7
263; RV64I-NEXT:    li a1, -8
264; RV64I-NEXT:    blt a1, a0, .LBB4_2
265; RV64I-NEXT:  .LBB4_4:
266; RV64I-NEXT:    li a0, -8
267; RV64I-NEXT:    ret
268;
269; RV32IZbb-LABEL: func3:
270; RV32IZbb:       # %bb.0:
271; RV32IZbb-NEXT:    add a0, a0, a1
272; RV32IZbb-NEXT:    li a1, 7
273; RV32IZbb-NEXT:    min a0, a0, a1
274; RV32IZbb-NEXT:    li a1, -8
275; RV32IZbb-NEXT:    max a0, a0, a1
276; RV32IZbb-NEXT:    ret
277;
278; RV64IZbb-LABEL: func3:
279; RV64IZbb:       # %bb.0:
280; RV64IZbb-NEXT:    add a0, a0, a1
281; RV64IZbb-NEXT:    li a1, 7
282; RV64IZbb-NEXT:    min a0, a0, a1
283; RV64IZbb-NEXT:    li a1, -8
284; RV64IZbb-NEXT:    max a0, a0, a1
285; RV64IZbb-NEXT:    ret
286  %tmp = call i4 @llvm.sadd.sat.i4(i4 %x, i4 %y);
287  ret i4 %tmp;
288}
289