xref: /llvm-project/llvm/test/CodeGen/RISCV/GlobalISel/combine-neg-abs.ll (revision 9020d193e6ef03e8070ac44078c5d8d9e86c4f2a)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2; RUN: llc -mtriple=riscv32 -global-isel -verify-machineinstrs < %s \
3; RUN:   | FileCheck %s --check-prefixes=RV32I
4; RUN: llc -mtriple=riscv32 -global-isel -mattr=+zbb -verify-machineinstrs < %s \
5; RUN:   | FileCheck %s --check-prefixes=RV32ZBB
6; RUN: llc -mtriple=riscv64 -global-isel -verify-machineinstrs < %s \
7; RUN:   | FileCheck %s --check-prefixes=RV64I
8; RUN: llc -mtriple=riscv64 -global-isel -mattr=+zbb -verify-machineinstrs < %s \
9; RUN:   | FileCheck %s --check-prefixes=RV64ZBB
10
11define i32 @expanded_neg_abs32(i32 %x) {
12; RV32I-LABEL: expanded_neg_abs32:
13; RV32I:       # %bb.0:
14; RV32I-NEXT:    neg a1, a0
15; RV32I-NEXT:    blt a0, a1, .LBB0_2
16; RV32I-NEXT:  # %bb.1:
17; RV32I-NEXT:    mv a1, a0
18; RV32I-NEXT:  .LBB0_2:
19; RV32I-NEXT:    neg a0, a1
20; RV32I-NEXT:    ret
21;
22; RV32ZBB-LABEL: expanded_neg_abs32:
23; RV32ZBB:       # %bb.0:
24; RV32ZBB-NEXT:    neg a1, a0
25; RV32ZBB-NEXT:    min a0, a0, a1
26; RV32ZBB-NEXT:    ret
27;
28; RV64I-LABEL: expanded_neg_abs32:
29; RV64I:       # %bb.0:
30; RV64I-NEXT:    negw a1, a0
31; RV64I-NEXT:    sext.w a2, a0
32; RV64I-NEXT:    blt a2, a1, .LBB0_2
33; RV64I-NEXT:  # %bb.1:
34; RV64I-NEXT:    mv a1, a0
35; RV64I-NEXT:  .LBB0_2:
36; RV64I-NEXT:    negw a0, a1
37; RV64I-NEXT:    ret
38;
39; RV64ZBB-LABEL: expanded_neg_abs32:
40; RV64ZBB:       # %bb.0:
41; RV64ZBB-NEXT:    negw a1, a0
42; RV64ZBB-NEXT:    sext.w a0, a0
43; RV64ZBB-NEXT:    max a0, a1, a0
44; RV64ZBB-NEXT:    negw a0, a0
45; RV64ZBB-NEXT:    ret
46  %n = sub i32 0, %x
47  %t = call i32 @llvm.smax.i32(i32 %n, i32 %x)
48  %r = sub i32 0, %t
49  ret i32 %r
50}
51
52define i32 @expanded_neg_abs32_unsigned(i32 %x) {
53; RV32I-LABEL: expanded_neg_abs32_unsigned:
54; RV32I:       # %bb.0:
55; RV32I-NEXT:    neg a1, a0
56; RV32I-NEXT:    bltu a0, a1, .LBB1_2
57; RV32I-NEXT:  # %bb.1:
58; RV32I-NEXT:    mv a1, a0
59; RV32I-NEXT:  .LBB1_2:
60; RV32I-NEXT:    neg a0, a1
61; RV32I-NEXT:    ret
62;
63; RV32ZBB-LABEL: expanded_neg_abs32_unsigned:
64; RV32ZBB:       # %bb.0:
65; RV32ZBB-NEXT:    neg a1, a0
66; RV32ZBB-NEXT:    minu a0, a0, a1
67; RV32ZBB-NEXT:    ret
68;
69; RV64I-LABEL: expanded_neg_abs32_unsigned:
70; RV64I:       # %bb.0:
71; RV64I-NEXT:    negw a1, a0
72; RV64I-NEXT:    sext.w a2, a0
73; RV64I-NEXT:    bltu a2, a1, .LBB1_2
74; RV64I-NEXT:  # %bb.1:
75; RV64I-NEXT:    mv a1, a0
76; RV64I-NEXT:  .LBB1_2:
77; RV64I-NEXT:    negw a0, a1
78; RV64I-NEXT:    ret
79;
80; RV64ZBB-LABEL: expanded_neg_abs32_unsigned:
81; RV64ZBB:       # %bb.0:
82; RV64ZBB-NEXT:    negw a1, a0
83; RV64ZBB-NEXT:    sext.w a0, a0
84; RV64ZBB-NEXT:    maxu a0, a1, a0
85; RV64ZBB-NEXT:    negw a0, a0
86; RV64ZBB-NEXT:    ret
87  %n = sub i32 0, %x
88  %t = call i32 @llvm.umax.i32(i32 %n, i32 %x)
89  %r = sub i32 0, %t
90  ret i32 %r
91}
92
93define i64 @expanded_neg_abs64(i64 %x) {
94; RV32I-LABEL: expanded_neg_abs64:
95; RV32I:       # %bb.0:
96; RV32I-NEXT:    snez a2, a0
97; RV32I-NEXT:    neg a3, a1
98; RV32I-NEXT:    sub a2, a3, a2
99; RV32I-NEXT:    neg a3, a0
100; RV32I-NEXT:    beq a2, a1, .LBB2_2
101; RV32I-NEXT:  # %bb.1:
102; RV32I-NEXT:    slt a4, a1, a2
103; RV32I-NEXT:    beqz a4, .LBB2_3
104; RV32I-NEXT:    j .LBB2_4
105; RV32I-NEXT:  .LBB2_2:
106; RV32I-NEXT:    sltu a4, a0, a3
107; RV32I-NEXT:    bnez a4, .LBB2_4
108; RV32I-NEXT:  .LBB2_3:
109; RV32I-NEXT:    mv a3, a0
110; RV32I-NEXT:    mv a2, a1
111; RV32I-NEXT:  .LBB2_4:
112; RV32I-NEXT:    neg a0, a3
113; RV32I-NEXT:    snez a1, a3
114; RV32I-NEXT:    neg a2, a2
115; RV32I-NEXT:    sub a1, a2, a1
116; RV32I-NEXT:    ret
117;
118; RV32ZBB-LABEL: expanded_neg_abs64:
119; RV32ZBB:       # %bb.0:
120; RV32ZBB-NEXT:    snez a2, a0
121; RV32ZBB-NEXT:    neg a3, a1
122; RV32ZBB-NEXT:    sub a2, a3, a2
123; RV32ZBB-NEXT:    neg a3, a0
124; RV32ZBB-NEXT:    beq a2, a1, .LBB2_2
125; RV32ZBB-NEXT:  # %bb.1:
126; RV32ZBB-NEXT:    slt a4, a1, a2
127; RV32ZBB-NEXT:    beqz a4, .LBB2_3
128; RV32ZBB-NEXT:    j .LBB2_4
129; RV32ZBB-NEXT:  .LBB2_2:
130; RV32ZBB-NEXT:    sltu a4, a0, a3
131; RV32ZBB-NEXT:    bnez a4, .LBB2_4
132; RV32ZBB-NEXT:  .LBB2_3:
133; RV32ZBB-NEXT:    mv a3, a0
134; RV32ZBB-NEXT:    mv a2, a1
135; RV32ZBB-NEXT:  .LBB2_4:
136; RV32ZBB-NEXT:    neg a0, a3
137; RV32ZBB-NEXT:    snez a1, a3
138; RV32ZBB-NEXT:    neg a2, a2
139; RV32ZBB-NEXT:    sub a1, a2, a1
140; RV32ZBB-NEXT:    ret
141;
142; RV64I-LABEL: expanded_neg_abs64:
143; RV64I:       # %bb.0:
144; RV64I-NEXT:    neg a1, a0
145; RV64I-NEXT:    blt a0, a1, .LBB2_2
146; RV64I-NEXT:  # %bb.1:
147; RV64I-NEXT:    mv a1, a0
148; RV64I-NEXT:  .LBB2_2:
149; RV64I-NEXT:    neg a0, a1
150; RV64I-NEXT:    ret
151;
152; RV64ZBB-LABEL: expanded_neg_abs64:
153; RV64ZBB:       # %bb.0:
154; RV64ZBB-NEXT:    neg a1, a0
155; RV64ZBB-NEXT:    min a0, a0, a1
156; RV64ZBB-NEXT:    ret
157  %n = sub i64 0, %x
158  %t = call i64 @llvm.smax.i64(i64 %n, i64 %x)
159  %r = sub i64 0, %t
160  ret i64 %r
161}
162
163define i64 @expanded_neg_abs64_unsigned(i64 %x) {
164; RV32I-LABEL: expanded_neg_abs64_unsigned:
165; RV32I:       # %bb.0:
166; RV32I-NEXT:    snez a2, a0
167; RV32I-NEXT:    neg a3, a1
168; RV32I-NEXT:    sub a2, a3, a2
169; RV32I-NEXT:    neg a3, a0
170; RV32I-NEXT:    beq a2, a1, .LBB3_2
171; RV32I-NEXT:  # %bb.1:
172; RV32I-NEXT:    sltu a4, a1, a2
173; RV32I-NEXT:    beqz a4, .LBB3_3
174; RV32I-NEXT:    j .LBB3_4
175; RV32I-NEXT:  .LBB3_2:
176; RV32I-NEXT:    sltu a4, a0, a3
177; RV32I-NEXT:    bnez a4, .LBB3_4
178; RV32I-NEXT:  .LBB3_3:
179; RV32I-NEXT:    mv a3, a0
180; RV32I-NEXT:    mv a2, a1
181; RV32I-NEXT:  .LBB3_4:
182; RV32I-NEXT:    neg a0, a3
183; RV32I-NEXT:    snez a1, a3
184; RV32I-NEXT:    neg a2, a2
185; RV32I-NEXT:    sub a1, a2, a1
186; RV32I-NEXT:    ret
187;
188; RV32ZBB-LABEL: expanded_neg_abs64_unsigned:
189; RV32ZBB:       # %bb.0:
190; RV32ZBB-NEXT:    snez a2, a0
191; RV32ZBB-NEXT:    neg a3, a1
192; RV32ZBB-NEXT:    sub a2, a3, a2
193; RV32ZBB-NEXT:    neg a3, a0
194; RV32ZBB-NEXT:    beq a2, a1, .LBB3_2
195; RV32ZBB-NEXT:  # %bb.1:
196; RV32ZBB-NEXT:    sltu a4, a1, a2
197; RV32ZBB-NEXT:    beqz a4, .LBB3_3
198; RV32ZBB-NEXT:    j .LBB3_4
199; RV32ZBB-NEXT:  .LBB3_2:
200; RV32ZBB-NEXT:    sltu a4, a0, a3
201; RV32ZBB-NEXT:    bnez a4, .LBB3_4
202; RV32ZBB-NEXT:  .LBB3_3:
203; RV32ZBB-NEXT:    mv a3, a0
204; RV32ZBB-NEXT:    mv a2, a1
205; RV32ZBB-NEXT:  .LBB3_4:
206; RV32ZBB-NEXT:    neg a0, a3
207; RV32ZBB-NEXT:    snez a1, a3
208; RV32ZBB-NEXT:    neg a2, a2
209; RV32ZBB-NEXT:    sub a1, a2, a1
210; RV32ZBB-NEXT:    ret
211;
212; RV64I-LABEL: expanded_neg_abs64_unsigned:
213; RV64I:       # %bb.0:
214; RV64I-NEXT:    neg a1, a0
215; RV64I-NEXT:    bltu a0, a1, .LBB3_2
216; RV64I-NEXT:  # %bb.1:
217; RV64I-NEXT:    mv a1, a0
218; RV64I-NEXT:  .LBB3_2:
219; RV64I-NEXT:    neg a0, a1
220; RV64I-NEXT:    ret
221;
222; RV64ZBB-LABEL: expanded_neg_abs64_unsigned:
223; RV64ZBB:       # %bb.0:
224; RV64ZBB-NEXT:    neg a1, a0
225; RV64ZBB-NEXT:    minu a0, a0, a1
226; RV64ZBB-NEXT:    ret
227  %n = sub i64 0, %x
228  %t = call i64 @llvm.umax.i64(i64 %n, i64 %x)
229  %r = sub i64 0, %t
230  ret i64 %r
231}
232
233define i32 @expanded_neg_inv_abs32(i32 %x) {
234; RV32I-LABEL: expanded_neg_inv_abs32:
235; RV32I:       # %bb.0:
236; RV32I-NEXT:    neg a1, a0
237; RV32I-NEXT:    blt a1, a0, .LBB4_2
238; RV32I-NEXT:  # %bb.1:
239; RV32I-NEXT:    mv a1, a0
240; RV32I-NEXT:  .LBB4_2:
241; RV32I-NEXT:    neg a0, a1
242; RV32I-NEXT:    ret
243;
244; RV32ZBB-LABEL: expanded_neg_inv_abs32:
245; RV32ZBB:       # %bb.0:
246; RV32ZBB-NEXT:    neg a1, a0
247; RV32ZBB-NEXT:    max a0, a0, a1
248; RV32ZBB-NEXT:    ret
249;
250; RV64I-LABEL: expanded_neg_inv_abs32:
251; RV64I:       # %bb.0:
252; RV64I-NEXT:    negw a1, a0
253; RV64I-NEXT:    sext.w a2, a0
254; RV64I-NEXT:    blt a1, a2, .LBB4_2
255; RV64I-NEXT:  # %bb.1:
256; RV64I-NEXT:    mv a1, a0
257; RV64I-NEXT:  .LBB4_2:
258; RV64I-NEXT:    negw a0, a1
259; RV64I-NEXT:    ret
260;
261; RV64ZBB-LABEL: expanded_neg_inv_abs32:
262; RV64ZBB:       # %bb.0:
263; RV64ZBB-NEXT:    negw a1, a0
264; RV64ZBB-NEXT:    sext.w a0, a0
265; RV64ZBB-NEXT:    min a0, a1, a0
266; RV64ZBB-NEXT:    negw a0, a0
267; RV64ZBB-NEXT:    ret
268  %n = sub i32 0, %x
269  %t = call i32 @llvm.smin.i32(i32 %n, i32 %x)
270  %r = sub i32 0, %t
271  ret i32 %r
272}
273
274define i32 @expanded_neg_inv_abs32_unsigned(i32 %x) {
275; RV32I-LABEL: expanded_neg_inv_abs32_unsigned:
276; RV32I:       # %bb.0:
277; RV32I-NEXT:    neg a1, a0
278; RV32I-NEXT:    bltu a1, a0, .LBB5_2
279; RV32I-NEXT:  # %bb.1:
280; RV32I-NEXT:    mv a1, a0
281; RV32I-NEXT:  .LBB5_2:
282; RV32I-NEXT:    neg a0, a1
283; RV32I-NEXT:    ret
284;
285; RV32ZBB-LABEL: expanded_neg_inv_abs32_unsigned:
286; RV32ZBB:       # %bb.0:
287; RV32ZBB-NEXT:    neg a1, a0
288; RV32ZBB-NEXT:    maxu a0, a0, a1
289; RV32ZBB-NEXT:    ret
290;
291; RV64I-LABEL: expanded_neg_inv_abs32_unsigned:
292; RV64I:       # %bb.0:
293; RV64I-NEXT:    negw a1, a0
294; RV64I-NEXT:    sext.w a2, a0
295; RV64I-NEXT:    bltu a1, a2, .LBB5_2
296; RV64I-NEXT:  # %bb.1:
297; RV64I-NEXT:    mv a1, a0
298; RV64I-NEXT:  .LBB5_2:
299; RV64I-NEXT:    negw a0, a1
300; RV64I-NEXT:    ret
301;
302; RV64ZBB-LABEL: expanded_neg_inv_abs32_unsigned:
303; RV64ZBB:       # %bb.0:
304; RV64ZBB-NEXT:    negw a1, a0
305; RV64ZBB-NEXT:    sext.w a0, a0
306; RV64ZBB-NEXT:    minu a0, a1, a0
307; RV64ZBB-NEXT:    negw a0, a0
308; RV64ZBB-NEXT:    ret
309  %n = sub i32 0, %x
310  %t = call i32 @llvm.umin.i32(i32 %n, i32 %x)
311  %r = sub i32 0, %t
312  ret i32 %r
313}
314
315define i64 @expanded_neg_inv_abs64(i64 %x) {
316; RV32I-LABEL: expanded_neg_inv_abs64:
317; RV32I:       # %bb.0:
318; RV32I-NEXT:    snez a2, a0
319; RV32I-NEXT:    neg a3, a1
320; RV32I-NEXT:    sub a2, a3, a2
321; RV32I-NEXT:    neg a3, a0
322; RV32I-NEXT:    beq a2, a1, .LBB6_2
323; RV32I-NEXT:  # %bb.1:
324; RV32I-NEXT:    slt a4, a2, a1
325; RV32I-NEXT:    beqz a4, .LBB6_3
326; RV32I-NEXT:    j .LBB6_4
327; RV32I-NEXT:  .LBB6_2:
328; RV32I-NEXT:    sltu a4, a3, a0
329; RV32I-NEXT:    bnez a4, .LBB6_4
330; RV32I-NEXT:  .LBB6_3:
331; RV32I-NEXT:    mv a3, a0
332; RV32I-NEXT:    mv a2, a1
333; RV32I-NEXT:  .LBB6_4:
334; RV32I-NEXT:    neg a0, a3
335; RV32I-NEXT:    snez a1, a3
336; RV32I-NEXT:    neg a2, a2
337; RV32I-NEXT:    sub a1, a2, a1
338; RV32I-NEXT:    ret
339;
340; RV32ZBB-LABEL: expanded_neg_inv_abs64:
341; RV32ZBB:       # %bb.0:
342; RV32ZBB-NEXT:    snez a2, a0
343; RV32ZBB-NEXT:    neg a3, a1
344; RV32ZBB-NEXT:    sub a2, a3, a2
345; RV32ZBB-NEXT:    neg a3, a0
346; RV32ZBB-NEXT:    beq a2, a1, .LBB6_2
347; RV32ZBB-NEXT:  # %bb.1:
348; RV32ZBB-NEXT:    slt a4, a2, a1
349; RV32ZBB-NEXT:    beqz a4, .LBB6_3
350; RV32ZBB-NEXT:    j .LBB6_4
351; RV32ZBB-NEXT:  .LBB6_2:
352; RV32ZBB-NEXT:    sltu a4, a3, a0
353; RV32ZBB-NEXT:    bnez a4, .LBB6_4
354; RV32ZBB-NEXT:  .LBB6_3:
355; RV32ZBB-NEXT:    mv a3, a0
356; RV32ZBB-NEXT:    mv a2, a1
357; RV32ZBB-NEXT:  .LBB6_4:
358; RV32ZBB-NEXT:    neg a0, a3
359; RV32ZBB-NEXT:    snez a1, a3
360; RV32ZBB-NEXT:    neg a2, a2
361; RV32ZBB-NEXT:    sub a1, a2, a1
362; RV32ZBB-NEXT:    ret
363;
364; RV64I-LABEL: expanded_neg_inv_abs64:
365; RV64I:       # %bb.0:
366; RV64I-NEXT:    neg a1, a0
367; RV64I-NEXT:    blt a1, a0, .LBB6_2
368; RV64I-NEXT:  # %bb.1:
369; RV64I-NEXT:    mv a1, a0
370; RV64I-NEXT:  .LBB6_2:
371; RV64I-NEXT:    neg a0, a1
372; RV64I-NEXT:    ret
373;
374; RV64ZBB-LABEL: expanded_neg_inv_abs64:
375; RV64ZBB:       # %bb.0:
376; RV64ZBB-NEXT:    neg a1, a0
377; RV64ZBB-NEXT:    max a0, a0, a1
378; RV64ZBB-NEXT:    ret
379  %n = sub i64 0, %x
380  %t = call i64 @llvm.smin.i64(i64 %n, i64 %x)
381  %r = sub i64 0, %t
382  ret i64 %r
383}
384
385define i64 @expanded_neg_inv_abs64_unsigned(i64 %x) {
386; RV32I-LABEL: expanded_neg_inv_abs64_unsigned:
387; RV32I:       # %bb.0:
388; RV32I-NEXT:    snez a2, a0
389; RV32I-NEXT:    neg a3, a1
390; RV32I-NEXT:    sub a2, a3, a2
391; RV32I-NEXT:    neg a3, a0
392; RV32I-NEXT:    beq a2, a1, .LBB7_2
393; RV32I-NEXT:  # %bb.1:
394; RV32I-NEXT:    sltu a4, a2, a1
395; RV32I-NEXT:    beqz a4, .LBB7_3
396; RV32I-NEXT:    j .LBB7_4
397; RV32I-NEXT:  .LBB7_2:
398; RV32I-NEXT:    sltu a4, a3, a0
399; RV32I-NEXT:    bnez a4, .LBB7_4
400; RV32I-NEXT:  .LBB7_3:
401; RV32I-NEXT:    mv a3, a0
402; RV32I-NEXT:    mv a2, a1
403; RV32I-NEXT:  .LBB7_4:
404; RV32I-NEXT:    neg a0, a3
405; RV32I-NEXT:    snez a1, a3
406; RV32I-NEXT:    neg a2, a2
407; RV32I-NEXT:    sub a1, a2, a1
408; RV32I-NEXT:    ret
409;
410; RV32ZBB-LABEL: expanded_neg_inv_abs64_unsigned:
411; RV32ZBB:       # %bb.0:
412; RV32ZBB-NEXT:    snez a2, a0
413; RV32ZBB-NEXT:    neg a3, a1
414; RV32ZBB-NEXT:    sub a2, a3, a2
415; RV32ZBB-NEXT:    neg a3, a0
416; RV32ZBB-NEXT:    beq a2, a1, .LBB7_2
417; RV32ZBB-NEXT:  # %bb.1:
418; RV32ZBB-NEXT:    sltu a4, a2, a1
419; RV32ZBB-NEXT:    beqz a4, .LBB7_3
420; RV32ZBB-NEXT:    j .LBB7_4
421; RV32ZBB-NEXT:  .LBB7_2:
422; RV32ZBB-NEXT:    sltu a4, a3, a0
423; RV32ZBB-NEXT:    bnez a4, .LBB7_4
424; RV32ZBB-NEXT:  .LBB7_3:
425; RV32ZBB-NEXT:    mv a3, a0
426; RV32ZBB-NEXT:    mv a2, a1
427; RV32ZBB-NEXT:  .LBB7_4:
428; RV32ZBB-NEXT:    neg a0, a3
429; RV32ZBB-NEXT:    snez a1, a3
430; RV32ZBB-NEXT:    neg a2, a2
431; RV32ZBB-NEXT:    sub a1, a2, a1
432; RV32ZBB-NEXT:    ret
433;
434; RV64I-LABEL: expanded_neg_inv_abs64_unsigned:
435; RV64I:       # %bb.0:
436; RV64I-NEXT:    neg a1, a0
437; RV64I-NEXT:    bltu a1, a0, .LBB7_2
438; RV64I-NEXT:  # %bb.1:
439; RV64I-NEXT:    mv a1, a0
440; RV64I-NEXT:  .LBB7_2:
441; RV64I-NEXT:    neg a0, a1
442; RV64I-NEXT:    ret
443;
444; RV64ZBB-LABEL: expanded_neg_inv_abs64_unsigned:
445; RV64ZBB:       # %bb.0:
446; RV64ZBB-NEXT:    neg a1, a0
447; RV64ZBB-NEXT:    maxu a0, a0, a1
448; RV64ZBB-NEXT:    ret
449  %n = sub i64 0, %x
450  %t = call i64 @llvm.umin.i64(i64 %n, i64 %x)
451  %r = sub i64 0, %t
452  ret i64 %r
453}
454