xref: /llvm-project/llvm/test/CodeGen/RISCV/usub_sat.ll (revision 86eff6be686a1e41e13c08ebfc2db4dd4d58e7c6)
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.usub.sat.i4(i4, i4)
8declare i8 @llvm.usub.sat.i8(i8, i8)
9declare i16 @llvm.usub.sat.i16(i16, i16)
10declare i32 @llvm.usub.sat.i32(i32, i32)
11declare i64 @llvm.usub.sat.i64(i64, i64)
12
13define signext i32 @func(i32 signext %x, i32 signext %y) nounwind {
14; RV32I-LABEL: func:
15; RV32I:       # %bb.0:
16; RV32I-NEXT:    sub a1, a0, a1
17; RV32I-NEXT:    sltu a0, a0, a1
18; RV32I-NEXT:    addi a0, a0, -1
19; RV32I-NEXT:    and a0, a0, a1
20; RV32I-NEXT:    ret
21;
22; RV64I-LABEL: func:
23; RV64I:       # %bb.0:
24; RV64I-NEXT:    subw a1, a0, a1
25; RV64I-NEXT:    sltu a0, a0, a1
26; RV64I-NEXT:    addi a0, a0, -1
27; RV64I-NEXT:    and a0, a0, a1
28; RV64I-NEXT:    ret
29;
30; RV32IZbb-LABEL: func:
31; RV32IZbb:       # %bb.0:
32; RV32IZbb-NEXT:    maxu a0, a0, a1
33; RV32IZbb-NEXT:    sub a0, a0, a1
34; RV32IZbb-NEXT:    ret
35;
36; RV64IZbb-LABEL: func:
37; RV64IZbb:       # %bb.0:
38; RV64IZbb-NEXT:    maxu a0, a0, a1
39; RV64IZbb-NEXT:    subw a0, a0, a1
40; RV64IZbb-NEXT:    ret
41  %tmp = call i32 @llvm.usub.sat.i32(i32 %x, i32 %y);
42  ret i32 %tmp;
43}
44
45define i64 @func2(i64 %x, i64 %y) nounwind {
46; RV32I-LABEL: func2:
47; RV32I:       # %bb.0:
48; RV32I-NEXT:    sltu a4, a0, a2
49; RV32I-NEXT:    sub a3, a1, a3
50; RV32I-NEXT:    sub a3, a3, a4
51; RV32I-NEXT:    sub a2, a0, a2
52; RV32I-NEXT:    beq a3, a1, .LBB1_2
53; RV32I-NEXT:  # %bb.1:
54; RV32I-NEXT:    sltu a0, a1, a3
55; RV32I-NEXT:    j .LBB1_3
56; RV32I-NEXT:  .LBB1_2:
57; RV32I-NEXT:    sltu a0, a0, a2
58; RV32I-NEXT:  .LBB1_3:
59; RV32I-NEXT:    addi a1, a0, -1
60; RV32I-NEXT:    and a0, a1, a2
61; RV32I-NEXT:    and a1, a1, a3
62; RV32I-NEXT:    ret
63;
64; RV64I-LABEL: func2:
65; RV64I:       # %bb.0:
66; RV64I-NEXT:    sub a1, a0, a1
67; RV64I-NEXT:    sltu a0, a0, a1
68; RV64I-NEXT:    addi a0, a0, -1
69; RV64I-NEXT:    and a0, a0, a1
70; RV64I-NEXT:    ret
71;
72; RV32IZbb-LABEL: func2:
73; RV32IZbb:       # %bb.0:
74; RV32IZbb-NEXT:    sltu a4, a0, a2
75; RV32IZbb-NEXT:    sub a3, a1, a3
76; RV32IZbb-NEXT:    sub a3, a3, a4
77; RV32IZbb-NEXT:    sub a2, a0, a2
78; RV32IZbb-NEXT:    beq a3, a1, .LBB1_2
79; RV32IZbb-NEXT:  # %bb.1:
80; RV32IZbb-NEXT:    sltu a0, a1, a3
81; RV32IZbb-NEXT:    j .LBB1_3
82; RV32IZbb-NEXT:  .LBB1_2:
83; RV32IZbb-NEXT:    sltu a0, a0, a2
84; RV32IZbb-NEXT:  .LBB1_3:
85; RV32IZbb-NEXT:    addi a1, a0, -1
86; RV32IZbb-NEXT:    and a0, a1, a2
87; RV32IZbb-NEXT:    and a1, a1, a3
88; RV32IZbb-NEXT:    ret
89;
90; RV64IZbb-LABEL: func2:
91; RV64IZbb:       # %bb.0:
92; RV64IZbb-NEXT:    maxu a0, a0, a1
93; RV64IZbb-NEXT:    sub a0, a0, a1
94; RV64IZbb-NEXT:    ret
95  %tmp = call i64 @llvm.usub.sat.i64(i64 %x, i64 %y);
96  ret i64 %tmp;
97}
98
99define zeroext i16 @func16(i16 zeroext %x, i16 zeroext %y) nounwind {
100; RV32I-LABEL: func16:
101; RV32I:       # %bb.0:
102; RV32I-NEXT:    sub a1, a0, a1
103; RV32I-NEXT:    sltu a0, a0, a1
104; RV32I-NEXT:    addi a0, a0, -1
105; RV32I-NEXT:    and a0, a0, a1
106; RV32I-NEXT:    ret
107;
108; RV64I-LABEL: func16:
109; RV64I:       # %bb.0:
110; RV64I-NEXT:    sub a1, a0, a1
111; RV64I-NEXT:    sltu a0, a0, a1
112; RV64I-NEXT:    addi a0, a0, -1
113; RV64I-NEXT:    and a0, a0, a1
114; RV64I-NEXT:    ret
115;
116; RV32IZbb-LABEL: func16:
117; RV32IZbb:       # %bb.0:
118; RV32IZbb-NEXT:    maxu a0, a0, a1
119; RV32IZbb-NEXT:    sub a0, a0, a1
120; RV32IZbb-NEXT:    ret
121;
122; RV64IZbb-LABEL: func16:
123; RV64IZbb:       # %bb.0:
124; RV64IZbb-NEXT:    maxu a0, a0, a1
125; RV64IZbb-NEXT:    sub a0, a0, a1
126; RV64IZbb-NEXT:    ret
127  %tmp = call i16 @llvm.usub.sat.i16(i16 %x, i16 %y);
128  ret i16 %tmp;
129}
130
131define zeroext i8 @func8(i8 zeroext %x, i8 zeroext %y) nounwind {
132; RV32I-LABEL: func8:
133; RV32I:       # %bb.0:
134; RV32I-NEXT:    sub a1, a0, a1
135; RV32I-NEXT:    sltu a0, a0, a1
136; RV32I-NEXT:    addi a0, a0, -1
137; RV32I-NEXT:    and a0, a0, a1
138; RV32I-NEXT:    ret
139;
140; RV64I-LABEL: func8:
141; RV64I:       # %bb.0:
142; RV64I-NEXT:    sub a1, a0, a1
143; RV64I-NEXT:    sltu a0, a0, a1
144; RV64I-NEXT:    addi a0, a0, -1
145; RV64I-NEXT:    and a0, a0, a1
146; RV64I-NEXT:    ret
147;
148; RV32IZbb-LABEL: func8:
149; RV32IZbb:       # %bb.0:
150; RV32IZbb-NEXT:    maxu a0, a0, a1
151; RV32IZbb-NEXT:    sub a0, a0, a1
152; RV32IZbb-NEXT:    ret
153;
154; RV64IZbb-LABEL: func8:
155; RV64IZbb:       # %bb.0:
156; RV64IZbb-NEXT:    maxu a0, a0, a1
157; RV64IZbb-NEXT:    sub a0, a0, a1
158; RV64IZbb-NEXT:    ret
159  %tmp = call i8 @llvm.usub.sat.i8(i8 %x, i8 %y);
160  ret i8 %tmp;
161}
162
163define zeroext i4 @func3(i4 zeroext %x, i4 zeroext %y) nounwind {
164; RV32I-LABEL: func3:
165; RV32I:       # %bb.0:
166; RV32I-NEXT:    sub a1, a0, a1
167; RV32I-NEXT:    sltu a0, a0, a1
168; RV32I-NEXT:    addi a0, a0, -1
169; RV32I-NEXT:    and a0, a0, a1
170; RV32I-NEXT:    ret
171;
172; RV64I-LABEL: func3:
173; RV64I:       # %bb.0:
174; RV64I-NEXT:    sub a1, a0, a1
175; RV64I-NEXT:    sltu a0, a0, a1
176; RV64I-NEXT:    addi a0, a0, -1
177; RV64I-NEXT:    and a0, a0, a1
178; RV64I-NEXT:    ret
179;
180; RV32IZbb-LABEL: func3:
181; RV32IZbb:       # %bb.0:
182; RV32IZbb-NEXT:    maxu a0, a0, a1
183; RV32IZbb-NEXT:    sub a0, a0, a1
184; RV32IZbb-NEXT:    ret
185;
186; RV64IZbb-LABEL: func3:
187; RV64IZbb:       # %bb.0:
188; RV64IZbb-NEXT:    maxu a0, a0, a1
189; RV64IZbb-NEXT:    sub a0, a0, a1
190; RV64IZbb-NEXT:    ret
191  %tmp = call i4 @llvm.usub.sat.i4(i4 %x, i4 %y);
192  ret i4 %tmp;
193}
194