1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3; RUN:   | FileCheck %s --check-prefix=RV32I
4; RUN: llc -mtriple=riscv32 -mattr=+zbb -verify-machineinstrs < %s \
5; RUN:   | FileCheck %s --check-prefix=RV32ZBB
6; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt -verify-machineinstrs < %s \
7; RUN:   | FileCheck %s --check-prefix=RV32ZBT
8; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
9; RUN:   | FileCheck %s --check-prefix=RV64I
10; RUN: llc -mtriple=riscv64 -mattr=+zbb -verify-machineinstrs < %s \
11; RUN:   | FileCheck %s --check-prefix=RV64ZBB
12; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbt -verify-machineinstrs < %s \
13; RUN:   | FileCheck %s --check-prefix=RV64ZBT
14
15declare i8 @llvm.abs.i8(i8, i1 immarg)
16declare i16 @llvm.abs.i16(i16, i1 immarg)
17declare i32 @llvm.abs.i32(i32, i1 immarg)
18declare i64 @llvm.abs.i64(i64, i1 immarg)
19declare i128 @llvm.abs.i128(i128, i1 immarg)
20
21define i8 @abs8(i8 %x) {
22; RV32I-LABEL: abs8:
23; RV32I:       # %bb.0:
24; RV32I-NEXT:    slli a1, a0, 24
25; RV32I-NEXT:    srai a1, a1, 31
26; RV32I-NEXT:    xor a0, a0, a1
27; RV32I-NEXT:    sub a0, a0, a1
28; RV32I-NEXT:    ret
29;
30; RV32ZBB-LABEL: abs8:
31; RV32ZBB:       # %bb.0:
32; RV32ZBB-NEXT:    sext.b a0, a0
33; RV32ZBB-NEXT:    neg a1, a0
34; RV32ZBB-NEXT:    max a0, a0, a1
35; RV32ZBB-NEXT:    ret
36;
37; RV32ZBT-LABEL: abs8:
38; RV32ZBT:       # %bb.0:
39; RV32ZBT-NEXT:    slli a1, a0, 24
40; RV32ZBT-NEXT:    srai a1, a1, 31
41; RV32ZBT-NEXT:    xor a0, a0, a1
42; RV32ZBT-NEXT:    sub a0, a0, a1
43; RV32ZBT-NEXT:    ret
44;
45; RV64I-LABEL: abs8:
46; RV64I:       # %bb.0:
47; RV64I-NEXT:    slli a1, a0, 56
48; RV64I-NEXT:    srai a1, a1, 63
49; RV64I-NEXT:    xor a0, a0, a1
50; RV64I-NEXT:    sub a0, a0, a1
51; RV64I-NEXT:    ret
52;
53; RV64ZBB-LABEL: abs8:
54; RV64ZBB:       # %bb.0:
55; RV64ZBB-NEXT:    sext.b a0, a0
56; RV64ZBB-NEXT:    neg a1, a0
57; RV64ZBB-NEXT:    max a0, a0, a1
58; RV64ZBB-NEXT:    ret
59;
60; RV64ZBT-LABEL: abs8:
61; RV64ZBT:       # %bb.0:
62; RV64ZBT-NEXT:    slli a1, a0, 56
63; RV64ZBT-NEXT:    srai a1, a1, 63
64; RV64ZBT-NEXT:    xor a0, a0, a1
65; RV64ZBT-NEXT:    sub a0, a0, a1
66; RV64ZBT-NEXT:    ret
67  %abs = tail call i8 @llvm.abs.i8(i8 %x, i1 true)
68  ret i8 %abs
69}
70
71define i8 @select_abs8(i8 %x) {
72; RV32I-LABEL: select_abs8:
73; RV32I:       # %bb.0:
74; RV32I-NEXT:    slli a1, a0, 24
75; RV32I-NEXT:    srai a1, a1, 31
76; RV32I-NEXT:    xor a0, a0, a1
77; RV32I-NEXT:    sub a0, a0, a1
78; RV32I-NEXT:    ret
79;
80; RV32ZBB-LABEL: select_abs8:
81; RV32ZBB:       # %bb.0:
82; RV32ZBB-NEXT:    sext.b a0, a0
83; RV32ZBB-NEXT:    neg a1, a0
84; RV32ZBB-NEXT:    max a0, a0, a1
85; RV32ZBB-NEXT:    ret
86;
87; RV32ZBT-LABEL: select_abs8:
88; RV32ZBT:       # %bb.0:
89; RV32ZBT-NEXT:    slli a1, a0, 24
90; RV32ZBT-NEXT:    srai a1, a1, 31
91; RV32ZBT-NEXT:    xor a0, a0, a1
92; RV32ZBT-NEXT:    sub a0, a0, a1
93; RV32ZBT-NEXT:    ret
94;
95; RV64I-LABEL: select_abs8:
96; RV64I:       # %bb.0:
97; RV64I-NEXT:    slli a1, a0, 56
98; RV64I-NEXT:    srai a1, a1, 63
99; RV64I-NEXT:    xor a0, a0, a1
100; RV64I-NEXT:    sub a0, a0, a1
101; RV64I-NEXT:    ret
102;
103; RV64ZBB-LABEL: select_abs8:
104; RV64ZBB:       # %bb.0:
105; RV64ZBB-NEXT:    sext.b a0, a0
106; RV64ZBB-NEXT:    neg a1, a0
107; RV64ZBB-NEXT:    max a0, a0, a1
108; RV64ZBB-NEXT:    ret
109;
110; RV64ZBT-LABEL: select_abs8:
111; RV64ZBT:       # %bb.0:
112; RV64ZBT-NEXT:    slli a1, a0, 56
113; RV64ZBT-NEXT:    srai a1, a1, 63
114; RV64ZBT-NEXT:    xor a0, a0, a1
115; RV64ZBT-NEXT:    sub a0, a0, a1
116; RV64ZBT-NEXT:    ret
117  %1 = icmp slt i8 %x, 0
118  %2 = sub nsw i8 0, %x
119  %3 = select i1 %1, i8 %2, i8 %x
120  ret i8 %3
121}
122
123define i16 @abs16(i16 %x) {
124; RV32I-LABEL: abs16:
125; RV32I:       # %bb.0:
126; RV32I-NEXT:    slli a1, a0, 16
127; RV32I-NEXT:    srai a1, a1, 31
128; RV32I-NEXT:    xor a0, a0, a1
129; RV32I-NEXT:    sub a0, a0, a1
130; RV32I-NEXT:    ret
131;
132; RV32ZBB-LABEL: abs16:
133; RV32ZBB:       # %bb.0:
134; RV32ZBB-NEXT:    sext.h a0, a0
135; RV32ZBB-NEXT:    neg a1, a0
136; RV32ZBB-NEXT:    max a0, a0, a1
137; RV32ZBB-NEXT:    ret
138;
139; RV32ZBT-LABEL: abs16:
140; RV32ZBT:       # %bb.0:
141; RV32ZBT-NEXT:    slli a1, a0, 16
142; RV32ZBT-NEXT:    srai a1, a1, 31
143; RV32ZBT-NEXT:    xor a0, a0, a1
144; RV32ZBT-NEXT:    sub a0, a0, a1
145; RV32ZBT-NEXT:    ret
146;
147; RV64I-LABEL: abs16:
148; RV64I:       # %bb.0:
149; RV64I-NEXT:    slli a1, a0, 48
150; RV64I-NEXT:    srai a1, a1, 63
151; RV64I-NEXT:    xor a0, a0, a1
152; RV64I-NEXT:    sub a0, a0, a1
153; RV64I-NEXT:    ret
154;
155; RV64ZBB-LABEL: abs16:
156; RV64ZBB:       # %bb.0:
157; RV64ZBB-NEXT:    sext.h a0, a0
158; RV64ZBB-NEXT:    neg a1, a0
159; RV64ZBB-NEXT:    max a0, a0, a1
160; RV64ZBB-NEXT:    ret
161;
162; RV64ZBT-LABEL: abs16:
163; RV64ZBT:       # %bb.0:
164; RV64ZBT-NEXT:    slli a1, a0, 48
165; RV64ZBT-NEXT:    srai a1, a1, 63
166; RV64ZBT-NEXT:    xor a0, a0, a1
167; RV64ZBT-NEXT:    sub a0, a0, a1
168; RV64ZBT-NEXT:    ret
169  %abs = tail call i16 @llvm.abs.i16(i16 %x, i1 true)
170  ret i16 %abs
171}
172
173define i16 @select_abs16(i16 %x) {
174; RV32I-LABEL: select_abs16:
175; RV32I:       # %bb.0:
176; RV32I-NEXT:    slli a1, a0, 16
177; RV32I-NEXT:    srai a1, a1, 31
178; RV32I-NEXT:    xor a0, a0, a1
179; RV32I-NEXT:    sub a0, a0, a1
180; RV32I-NEXT:    ret
181;
182; RV32ZBB-LABEL: select_abs16:
183; RV32ZBB:       # %bb.0:
184; RV32ZBB-NEXT:    sext.h a0, a0
185; RV32ZBB-NEXT:    neg a1, a0
186; RV32ZBB-NEXT:    max a0, a0, a1
187; RV32ZBB-NEXT:    ret
188;
189; RV32ZBT-LABEL: select_abs16:
190; RV32ZBT:       # %bb.0:
191; RV32ZBT-NEXT:    slli a1, a0, 16
192; RV32ZBT-NEXT:    srai a1, a1, 31
193; RV32ZBT-NEXT:    xor a0, a0, a1
194; RV32ZBT-NEXT:    sub a0, a0, a1
195; RV32ZBT-NEXT:    ret
196;
197; RV64I-LABEL: select_abs16:
198; RV64I:       # %bb.0:
199; RV64I-NEXT:    slli a1, a0, 48
200; RV64I-NEXT:    srai a1, a1, 63
201; RV64I-NEXT:    xor a0, a0, a1
202; RV64I-NEXT:    sub a0, a0, a1
203; RV64I-NEXT:    ret
204;
205; RV64ZBB-LABEL: select_abs16:
206; RV64ZBB:       # %bb.0:
207; RV64ZBB-NEXT:    sext.h a0, a0
208; RV64ZBB-NEXT:    neg a1, a0
209; RV64ZBB-NEXT:    max a0, a0, a1
210; RV64ZBB-NEXT:    ret
211;
212; RV64ZBT-LABEL: select_abs16:
213; RV64ZBT:       # %bb.0:
214; RV64ZBT-NEXT:    slli a1, a0, 48
215; RV64ZBT-NEXT:    srai a1, a1, 63
216; RV64ZBT-NEXT:    xor a0, a0, a1
217; RV64ZBT-NEXT:    sub a0, a0, a1
218; RV64ZBT-NEXT:    ret
219  %1 = icmp slt i16 %x, 0
220  %2 = sub nsw i16 0, %x
221  %3 = select i1 %1, i16 %2, i16 %x
222  ret i16 %3
223}
224
225define i32 @abs32(i32 %x) {
226; RV32I-LABEL: abs32:
227; RV32I:       # %bb.0:
228; RV32I-NEXT:    srai a1, a0, 31
229; RV32I-NEXT:    xor a0, a0, a1
230; RV32I-NEXT:    sub a0, a0, a1
231; RV32I-NEXT:    ret
232;
233; RV32ZBB-LABEL: abs32:
234; RV32ZBB:       # %bb.0:
235; RV32ZBB-NEXT:    neg a1, a0
236; RV32ZBB-NEXT:    max a0, a0, a1
237; RV32ZBB-NEXT:    ret
238;
239; RV32ZBT-LABEL: abs32:
240; RV32ZBT:       # %bb.0:
241; RV32ZBT-NEXT:    srai a1, a0, 31
242; RV32ZBT-NEXT:    xor a0, a0, a1
243; RV32ZBT-NEXT:    sub a0, a0, a1
244; RV32ZBT-NEXT:    ret
245;
246; RV64I-LABEL: abs32:
247; RV64I:       # %bb.0:
248; RV64I-NEXT:    sraiw a1, a0, 31
249; RV64I-NEXT:    xor a0, a0, a1
250; RV64I-NEXT:    subw a0, a0, a1
251; RV64I-NEXT:    ret
252;
253; RV64ZBB-LABEL: abs32:
254; RV64ZBB:       # %bb.0:
255; RV64ZBB-NEXT:    sext.w a0, a0
256; RV64ZBB-NEXT:    neg a1, a0
257; RV64ZBB-NEXT:    max a0, a0, a1
258; RV64ZBB-NEXT:    ret
259;
260; RV64ZBT-LABEL: abs32:
261; RV64ZBT:       # %bb.0:
262; RV64ZBT-NEXT:    sraiw a1, a0, 31
263; RV64ZBT-NEXT:    xor a0, a0, a1
264; RV64ZBT-NEXT:    subw a0, a0, a1
265; RV64ZBT-NEXT:    ret
266  %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true)
267  ret i32 %abs
268}
269
270define i32 @select_abs32(i32 %x) {
271; RV32I-LABEL: select_abs32:
272; RV32I:       # %bb.0:
273; RV32I-NEXT:    srai a1, a0, 31
274; RV32I-NEXT:    xor a0, a0, a1
275; RV32I-NEXT:    sub a0, a0, a1
276; RV32I-NEXT:    ret
277;
278; RV32ZBB-LABEL: select_abs32:
279; RV32ZBB:       # %bb.0:
280; RV32ZBB-NEXT:    neg a1, a0
281; RV32ZBB-NEXT:    max a0, a0, a1
282; RV32ZBB-NEXT:    ret
283;
284; RV32ZBT-LABEL: select_abs32:
285; RV32ZBT:       # %bb.0:
286; RV32ZBT-NEXT:    srai a1, a0, 31
287; RV32ZBT-NEXT:    xor a0, a0, a1
288; RV32ZBT-NEXT:    sub a0, a0, a1
289; RV32ZBT-NEXT:    ret
290;
291; RV64I-LABEL: select_abs32:
292; RV64I:       # %bb.0:
293; RV64I-NEXT:    sraiw a1, a0, 31
294; RV64I-NEXT:    xor a0, a0, a1
295; RV64I-NEXT:    subw a0, a0, a1
296; RV64I-NEXT:    ret
297;
298; RV64ZBB-LABEL: select_abs32:
299; RV64ZBB:       # %bb.0:
300; RV64ZBB-NEXT:    sext.w a0, a0
301; RV64ZBB-NEXT:    neg a1, a0
302; RV64ZBB-NEXT:    max a0, a0, a1
303; RV64ZBB-NEXT:    ret
304;
305; RV64ZBT-LABEL: select_abs32:
306; RV64ZBT:       # %bb.0:
307; RV64ZBT-NEXT:    sraiw a1, a0, 31
308; RV64ZBT-NEXT:    xor a0, a0, a1
309; RV64ZBT-NEXT:    subw a0, a0, a1
310; RV64ZBT-NEXT:    ret
311  %1 = icmp slt i32 %x, 0
312  %2 = sub nsw i32 0, %x
313  %3 = select i1 %1, i32 %2, i32 %x
314  ret i32 %3
315}
316
317define i64 @abs64(i64 %x) {
318; RV32I-LABEL: abs64:
319; RV32I:       # %bb.0:
320; RV32I-NEXT:    bgez a1, .LBB6_2
321; RV32I-NEXT:  # %bb.1:
322; RV32I-NEXT:    snez a2, a0
323; RV32I-NEXT:    neg a0, a0
324; RV32I-NEXT:    add a1, a1, a2
325; RV32I-NEXT:    neg a1, a1
326; RV32I-NEXT:  .LBB6_2:
327; RV32I-NEXT:    ret
328;
329; RV32ZBB-LABEL: abs64:
330; RV32ZBB:       # %bb.0:
331; RV32ZBB-NEXT:    bgez a1, .LBB6_2
332; RV32ZBB-NEXT:  # %bb.1:
333; RV32ZBB-NEXT:    snez a2, a0
334; RV32ZBB-NEXT:    neg a0, a0
335; RV32ZBB-NEXT:    add a1, a1, a2
336; RV32ZBB-NEXT:    neg a1, a1
337; RV32ZBB-NEXT:  .LBB6_2:
338; RV32ZBB-NEXT:    ret
339;
340; RV32ZBT-LABEL: abs64:
341; RV32ZBT:       # %bb.0:
342; RV32ZBT-NEXT:    neg a2, a0
343; RV32ZBT-NEXT:    slti a3, a1, 0
344; RV32ZBT-NEXT:    cmov a2, a3, a2, a0
345; RV32ZBT-NEXT:    snez a0, a0
346; RV32ZBT-NEXT:    add a0, a1, a0
347; RV32ZBT-NEXT:    neg a0, a0
348; RV32ZBT-NEXT:    cmov a1, a3, a0, a1
349; RV32ZBT-NEXT:    mv a0, a2
350; RV32ZBT-NEXT:    ret
351;
352; RV64I-LABEL: abs64:
353; RV64I:       # %bb.0:
354; RV64I-NEXT:    srai a1, a0, 63
355; RV64I-NEXT:    xor a0, a0, a1
356; RV64I-NEXT:    sub a0, a0, a1
357; RV64I-NEXT:    ret
358;
359; RV64ZBB-LABEL: abs64:
360; RV64ZBB:       # %bb.0:
361; RV64ZBB-NEXT:    neg a1, a0
362; RV64ZBB-NEXT:    max a0, a0, a1
363; RV64ZBB-NEXT:    ret
364;
365; RV64ZBT-LABEL: abs64:
366; RV64ZBT:       # %bb.0:
367; RV64ZBT-NEXT:    srai a1, a0, 63
368; RV64ZBT-NEXT:    xor a0, a0, a1
369; RV64ZBT-NEXT:    sub a0, a0, a1
370; RV64ZBT-NEXT:    ret
371  %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
372  ret i64 %abs
373}
374
375define i64 @select_abs64(i64 %x) {
376; RV32I-LABEL: select_abs64:
377; RV32I:       # %bb.0:
378; RV32I-NEXT:    bgez a1, .LBB7_2
379; RV32I-NEXT:  # %bb.1:
380; RV32I-NEXT:    snez a2, a0
381; RV32I-NEXT:    neg a0, a0
382; RV32I-NEXT:    add a1, a1, a2
383; RV32I-NEXT:    neg a1, a1
384; RV32I-NEXT:  .LBB7_2:
385; RV32I-NEXT:    ret
386;
387; RV32ZBB-LABEL: select_abs64:
388; RV32ZBB:       # %bb.0:
389; RV32ZBB-NEXT:    bgez a1, .LBB7_2
390; RV32ZBB-NEXT:  # %bb.1:
391; RV32ZBB-NEXT:    snez a2, a0
392; RV32ZBB-NEXT:    neg a0, a0
393; RV32ZBB-NEXT:    add a1, a1, a2
394; RV32ZBB-NEXT:    neg a1, a1
395; RV32ZBB-NEXT:  .LBB7_2:
396; RV32ZBB-NEXT:    ret
397;
398; RV32ZBT-LABEL: select_abs64:
399; RV32ZBT:       # %bb.0:
400; RV32ZBT-NEXT:    neg a2, a0
401; RV32ZBT-NEXT:    slti a3, a1, 0
402; RV32ZBT-NEXT:    cmov a2, a3, a2, a0
403; RV32ZBT-NEXT:    snez a0, a0
404; RV32ZBT-NEXT:    add a0, a1, a0
405; RV32ZBT-NEXT:    neg a0, a0
406; RV32ZBT-NEXT:    cmov a1, a3, a0, a1
407; RV32ZBT-NEXT:    mv a0, a2
408; RV32ZBT-NEXT:    ret
409;
410; RV64I-LABEL: select_abs64:
411; RV64I:       # %bb.0:
412; RV64I-NEXT:    srai a1, a0, 63
413; RV64I-NEXT:    xor a0, a0, a1
414; RV64I-NEXT:    sub a0, a0, a1
415; RV64I-NEXT:    ret
416;
417; RV64ZBB-LABEL: select_abs64:
418; RV64ZBB:       # %bb.0:
419; RV64ZBB-NEXT:    neg a1, a0
420; RV64ZBB-NEXT:    max a0, a0, a1
421; RV64ZBB-NEXT:    ret
422;
423; RV64ZBT-LABEL: select_abs64:
424; RV64ZBT:       # %bb.0:
425; RV64ZBT-NEXT:    srai a1, a0, 63
426; RV64ZBT-NEXT:    xor a0, a0, a1
427; RV64ZBT-NEXT:    sub a0, a0, a1
428; RV64ZBT-NEXT:    ret
429  %1 = icmp slt i64 %x, 0
430  %2 = sub nsw i64 0, %x
431  %3 = select i1 %1, i64 %2, i64 %x
432  ret i64 %3
433}
434
435define i128 @abs128(i128 %x) {
436; RV32I-LABEL: abs128:
437; RV32I:       # %bb.0:
438; RV32I-NEXT:    lw a3, 0(a1)
439; RV32I-NEXT:    lw a2, 4(a1)
440; RV32I-NEXT:    lw a4, 12(a1)
441; RV32I-NEXT:    snez a5, a3
442; RV32I-NEXT:    mv a6, a5
443; RV32I-NEXT:    beqz a2, .LBB8_2
444; RV32I-NEXT:  # %bb.1:
445; RV32I-NEXT:    snez a6, a2
446; RV32I-NEXT:  .LBB8_2:
447; RV32I-NEXT:    lw a1, 8(a1)
448; RV32I-NEXT:    bgez a4, .LBB8_4
449; RV32I-NEXT:  # %bb.3:
450; RV32I-NEXT:    neg a7, a1
451; RV32I-NEXT:    sltu t0, a7, a6
452; RV32I-NEXT:    snez a1, a1
453; RV32I-NEXT:    add a1, a4, a1
454; RV32I-NEXT:    add a1, a1, t0
455; RV32I-NEXT:    neg a4, a1
456; RV32I-NEXT:    sub a1, a7, a6
457; RV32I-NEXT:    add a2, a2, a5
458; RV32I-NEXT:    neg a2, a2
459; RV32I-NEXT:    neg a3, a3
460; RV32I-NEXT:  .LBB8_4:
461; RV32I-NEXT:    sw a3, 0(a0)
462; RV32I-NEXT:    sw a1, 8(a0)
463; RV32I-NEXT:    sw a2, 4(a0)
464; RV32I-NEXT:    sw a4, 12(a0)
465; RV32I-NEXT:    ret
466;
467; RV32ZBB-LABEL: abs128:
468; RV32ZBB:       # %bb.0:
469; RV32ZBB-NEXT:    lw a3, 0(a1)
470; RV32ZBB-NEXT:    lw a2, 4(a1)
471; RV32ZBB-NEXT:    lw a4, 12(a1)
472; RV32ZBB-NEXT:    snez a5, a3
473; RV32ZBB-NEXT:    mv a6, a5
474; RV32ZBB-NEXT:    beqz a2, .LBB8_2
475; RV32ZBB-NEXT:  # %bb.1:
476; RV32ZBB-NEXT:    snez a6, a2
477; RV32ZBB-NEXT:  .LBB8_2:
478; RV32ZBB-NEXT:    lw a1, 8(a1)
479; RV32ZBB-NEXT:    bgez a4, .LBB8_4
480; RV32ZBB-NEXT:  # %bb.3:
481; RV32ZBB-NEXT:    neg a7, a1
482; RV32ZBB-NEXT:    sltu t0, a7, a6
483; RV32ZBB-NEXT:    snez a1, a1
484; RV32ZBB-NEXT:    add a1, a4, a1
485; RV32ZBB-NEXT:    add a1, a1, t0
486; RV32ZBB-NEXT:    neg a4, a1
487; RV32ZBB-NEXT:    sub a1, a7, a6
488; RV32ZBB-NEXT:    add a2, a2, a5
489; RV32ZBB-NEXT:    neg a2, a2
490; RV32ZBB-NEXT:    neg a3, a3
491; RV32ZBB-NEXT:  .LBB8_4:
492; RV32ZBB-NEXT:    sw a3, 0(a0)
493; RV32ZBB-NEXT:    sw a1, 8(a0)
494; RV32ZBB-NEXT:    sw a2, 4(a0)
495; RV32ZBB-NEXT:    sw a4, 12(a0)
496; RV32ZBB-NEXT:    ret
497;
498; RV32ZBT-LABEL: abs128:
499; RV32ZBT:       # %bb.0:
500; RV32ZBT-NEXT:    lw a2, 0(a1)
501; RV32ZBT-NEXT:    lw a3, 4(a1)
502; RV32ZBT-NEXT:    lw a4, 12(a1)
503; RV32ZBT-NEXT:    lw a1, 8(a1)
504; RV32ZBT-NEXT:    snez a5, a2
505; RV32ZBT-NEXT:    snez a6, a3
506; RV32ZBT-NEXT:    cmov a6, a3, a6, a5
507; RV32ZBT-NEXT:    neg a7, a1
508; RV32ZBT-NEXT:    sltu t0, a7, a6
509; RV32ZBT-NEXT:    snez t1, a1
510; RV32ZBT-NEXT:    add t1, a4, t1
511; RV32ZBT-NEXT:    add t0, t1, t0
512; RV32ZBT-NEXT:    neg t0, t0
513; RV32ZBT-NEXT:    slti t1, a4, 0
514; RV32ZBT-NEXT:    cmov a4, t1, t0, a4
515; RV32ZBT-NEXT:    sub a6, a7, a6
516; RV32ZBT-NEXT:    cmov a1, t1, a6, a1
517; RV32ZBT-NEXT:    add a5, a3, a5
518; RV32ZBT-NEXT:    neg a5, a5
519; RV32ZBT-NEXT:    cmov a3, t1, a5, a3
520; RV32ZBT-NEXT:    neg a5, a2
521; RV32ZBT-NEXT:    cmov a2, t1, a5, a2
522; RV32ZBT-NEXT:    sw a2, 0(a0)
523; RV32ZBT-NEXT:    sw a1, 8(a0)
524; RV32ZBT-NEXT:    sw a3, 4(a0)
525; RV32ZBT-NEXT:    sw a4, 12(a0)
526; RV32ZBT-NEXT:    ret
527;
528; RV64I-LABEL: abs128:
529; RV64I:       # %bb.0:
530; RV64I-NEXT:    bgez a1, .LBB8_2
531; RV64I-NEXT:  # %bb.1:
532; RV64I-NEXT:    snez a2, a0
533; RV64I-NEXT:    neg a0, a0
534; RV64I-NEXT:    add a1, a1, a2
535; RV64I-NEXT:    neg a1, a1
536; RV64I-NEXT:  .LBB8_2:
537; RV64I-NEXT:    ret
538;
539; RV64ZBB-LABEL: abs128:
540; RV64ZBB:       # %bb.0:
541; RV64ZBB-NEXT:    bgez a1, .LBB8_2
542; RV64ZBB-NEXT:  # %bb.1:
543; RV64ZBB-NEXT:    snez a2, a0
544; RV64ZBB-NEXT:    neg a0, a0
545; RV64ZBB-NEXT:    add a1, a1, a2
546; RV64ZBB-NEXT:    neg a1, a1
547; RV64ZBB-NEXT:  .LBB8_2:
548; RV64ZBB-NEXT:    ret
549;
550; RV64ZBT-LABEL: abs128:
551; RV64ZBT:       # %bb.0:
552; RV64ZBT-NEXT:    neg a2, a0
553; RV64ZBT-NEXT:    slti a3, a1, 0
554; RV64ZBT-NEXT:    cmov a2, a3, a2, a0
555; RV64ZBT-NEXT:    snez a0, a0
556; RV64ZBT-NEXT:    add a0, a1, a0
557; RV64ZBT-NEXT:    neg a0, a0
558; RV64ZBT-NEXT:    cmov a1, a3, a0, a1
559; RV64ZBT-NEXT:    mv a0, a2
560; RV64ZBT-NEXT:    ret
561  %abs = tail call i128 @llvm.abs.i128(i128 %x, i1 true)
562  ret i128 %abs
563}
564
565define i128 @select_abs128(i128 %x) {
566; RV32I-LABEL: select_abs128:
567; RV32I:       # %bb.0:
568; RV32I-NEXT:    lw a3, 0(a1)
569; RV32I-NEXT:    lw a2, 4(a1)
570; RV32I-NEXT:    lw a4, 12(a1)
571; RV32I-NEXT:    snez a5, a3
572; RV32I-NEXT:    mv a6, a5
573; RV32I-NEXT:    beqz a2, .LBB9_2
574; RV32I-NEXT:  # %bb.1:
575; RV32I-NEXT:    snez a6, a2
576; RV32I-NEXT:  .LBB9_2:
577; RV32I-NEXT:    lw a1, 8(a1)
578; RV32I-NEXT:    bgez a4, .LBB9_4
579; RV32I-NEXT:  # %bb.3:
580; RV32I-NEXT:    neg a7, a1
581; RV32I-NEXT:    sltu t0, a7, a6
582; RV32I-NEXT:    snez a1, a1
583; RV32I-NEXT:    add a1, a4, a1
584; RV32I-NEXT:    add a1, a1, t0
585; RV32I-NEXT:    neg a4, a1
586; RV32I-NEXT:    sub a1, a7, a6
587; RV32I-NEXT:    add a2, a2, a5
588; RV32I-NEXT:    neg a2, a2
589; RV32I-NEXT:    neg a3, a3
590; RV32I-NEXT:  .LBB9_4:
591; RV32I-NEXT:    sw a3, 0(a0)
592; RV32I-NEXT:    sw a1, 8(a0)
593; RV32I-NEXT:    sw a2, 4(a0)
594; RV32I-NEXT:    sw a4, 12(a0)
595; RV32I-NEXT:    ret
596;
597; RV32ZBB-LABEL: select_abs128:
598; RV32ZBB:       # %bb.0:
599; RV32ZBB-NEXT:    lw a3, 0(a1)
600; RV32ZBB-NEXT:    lw a2, 4(a1)
601; RV32ZBB-NEXT:    lw a4, 12(a1)
602; RV32ZBB-NEXT:    snez a5, a3
603; RV32ZBB-NEXT:    mv a6, a5
604; RV32ZBB-NEXT:    beqz a2, .LBB9_2
605; RV32ZBB-NEXT:  # %bb.1:
606; RV32ZBB-NEXT:    snez a6, a2
607; RV32ZBB-NEXT:  .LBB9_2:
608; RV32ZBB-NEXT:    lw a1, 8(a1)
609; RV32ZBB-NEXT:    bgez a4, .LBB9_4
610; RV32ZBB-NEXT:  # %bb.3:
611; RV32ZBB-NEXT:    neg a7, a1
612; RV32ZBB-NEXT:    sltu t0, a7, a6
613; RV32ZBB-NEXT:    snez a1, a1
614; RV32ZBB-NEXT:    add a1, a4, a1
615; RV32ZBB-NEXT:    add a1, a1, t0
616; RV32ZBB-NEXT:    neg a4, a1
617; RV32ZBB-NEXT:    sub a1, a7, a6
618; RV32ZBB-NEXT:    add a2, a2, a5
619; RV32ZBB-NEXT:    neg a2, a2
620; RV32ZBB-NEXT:    neg a3, a3
621; RV32ZBB-NEXT:  .LBB9_4:
622; RV32ZBB-NEXT:    sw a3, 0(a0)
623; RV32ZBB-NEXT:    sw a1, 8(a0)
624; RV32ZBB-NEXT:    sw a2, 4(a0)
625; RV32ZBB-NEXT:    sw a4, 12(a0)
626; RV32ZBB-NEXT:    ret
627;
628; RV32ZBT-LABEL: select_abs128:
629; RV32ZBT:       # %bb.0:
630; RV32ZBT-NEXT:    lw a2, 0(a1)
631; RV32ZBT-NEXT:    lw a3, 4(a1)
632; RV32ZBT-NEXT:    lw a4, 12(a1)
633; RV32ZBT-NEXT:    lw a1, 8(a1)
634; RV32ZBT-NEXT:    snez a5, a2
635; RV32ZBT-NEXT:    snez a6, a3
636; RV32ZBT-NEXT:    cmov a6, a3, a6, a5
637; RV32ZBT-NEXT:    neg a7, a1
638; RV32ZBT-NEXT:    sltu t0, a7, a6
639; RV32ZBT-NEXT:    snez t1, a1
640; RV32ZBT-NEXT:    add t1, a4, t1
641; RV32ZBT-NEXT:    add t0, t1, t0
642; RV32ZBT-NEXT:    neg t0, t0
643; RV32ZBT-NEXT:    slti t1, a4, 0
644; RV32ZBT-NEXT:    cmov a4, t1, t0, a4
645; RV32ZBT-NEXT:    sub a6, a7, a6
646; RV32ZBT-NEXT:    cmov a1, t1, a6, a1
647; RV32ZBT-NEXT:    add a5, a3, a5
648; RV32ZBT-NEXT:    neg a5, a5
649; RV32ZBT-NEXT:    cmov a3, t1, a5, a3
650; RV32ZBT-NEXT:    neg a5, a2
651; RV32ZBT-NEXT:    cmov a2, t1, a5, a2
652; RV32ZBT-NEXT:    sw a2, 0(a0)
653; RV32ZBT-NEXT:    sw a1, 8(a0)
654; RV32ZBT-NEXT:    sw a3, 4(a0)
655; RV32ZBT-NEXT:    sw a4, 12(a0)
656; RV32ZBT-NEXT:    ret
657;
658; RV64I-LABEL: select_abs128:
659; RV64I:       # %bb.0:
660; RV64I-NEXT:    bgez a1, .LBB9_2
661; RV64I-NEXT:  # %bb.1:
662; RV64I-NEXT:    snez a2, a0
663; RV64I-NEXT:    neg a0, a0
664; RV64I-NEXT:    add a1, a1, a2
665; RV64I-NEXT:    neg a1, a1
666; RV64I-NEXT:  .LBB9_2:
667; RV64I-NEXT:    ret
668;
669; RV64ZBB-LABEL: select_abs128:
670; RV64ZBB:       # %bb.0:
671; RV64ZBB-NEXT:    bgez a1, .LBB9_2
672; RV64ZBB-NEXT:  # %bb.1:
673; RV64ZBB-NEXT:    snez a2, a0
674; RV64ZBB-NEXT:    neg a0, a0
675; RV64ZBB-NEXT:    add a1, a1, a2
676; RV64ZBB-NEXT:    neg a1, a1
677; RV64ZBB-NEXT:  .LBB9_2:
678; RV64ZBB-NEXT:    ret
679;
680; RV64ZBT-LABEL: select_abs128:
681; RV64ZBT:       # %bb.0:
682; RV64ZBT-NEXT:    neg a2, a0
683; RV64ZBT-NEXT:    slti a3, a1, 0
684; RV64ZBT-NEXT:    cmov a2, a3, a2, a0
685; RV64ZBT-NEXT:    snez a0, a0
686; RV64ZBT-NEXT:    add a0, a1, a0
687; RV64ZBT-NEXT:    neg a0, a0
688; RV64ZBT-NEXT:    cmov a1, a3, a0, a1
689; RV64ZBT-NEXT:    mv a0, a2
690; RV64ZBT-NEXT:    ret
691  %1 = icmp slt i128 %x, 0
692  %2 = sub nsw i128 0, %x
693  %3 = select i1 %1, i128 %2, i128 %x
694  ret i128 %3
695}
696
697define i64 @zext_abs32(i32 %x) {
698; RV32I-LABEL: zext_abs32:
699; RV32I:       # %bb.0:
700; RV32I-NEXT:    srai a1, a0, 31
701; RV32I-NEXT:    xor a0, a0, a1
702; RV32I-NEXT:    sub a0, a0, a1
703; RV32I-NEXT:    li a1, 0
704; RV32I-NEXT:    ret
705;
706; RV32ZBB-LABEL: zext_abs32:
707; RV32ZBB:       # %bb.0:
708; RV32ZBB-NEXT:    neg a1, a0
709; RV32ZBB-NEXT:    max a0, a0, a1
710; RV32ZBB-NEXT:    li a1, 0
711; RV32ZBB-NEXT:    ret
712;
713; RV32ZBT-LABEL: zext_abs32:
714; RV32ZBT:       # %bb.0:
715; RV32ZBT-NEXT:    srai a1, a0, 31
716; RV32ZBT-NEXT:    xor a0, a0, a1
717; RV32ZBT-NEXT:    sub a0, a0, a1
718; RV32ZBT-NEXT:    li a1, 0
719; RV32ZBT-NEXT:    ret
720;
721; RV64I-LABEL: zext_abs32:
722; RV64I:       # %bb.0:
723; RV64I-NEXT:    sraiw a1, a0, 31
724; RV64I-NEXT:    xor a0, a0, a1
725; RV64I-NEXT:    subw a0, a0, a1
726; RV64I-NEXT:    ret
727;
728; RV64ZBB-LABEL: zext_abs32:
729; RV64ZBB:       # %bb.0:
730; RV64ZBB-NEXT:    sext.w a0, a0
731; RV64ZBB-NEXT:    negw a1, a0
732; RV64ZBB-NEXT:    max a0, a0, a1
733; RV64ZBB-NEXT:    ret
734;
735; RV64ZBT-LABEL: zext_abs32:
736; RV64ZBT:       # %bb.0:
737; RV64ZBT-NEXT:    sraiw a1, a0, 31
738; RV64ZBT-NEXT:    xor a0, a0, a1
739; RV64ZBT-NEXT:    subw a0, a0, a1
740; RV64ZBT-NEXT:    ret
741  %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true)
742  %zext = zext i32 %abs to i64
743  ret i64 %zext
744}
745