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=+experimental-zbt -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s --check-prefix=RV32IBT
6 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
7 ; RUN: | FileCheck %s --check-prefix=RV64I
8 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbt -verify-machineinstrs < %s \
9 ; RUN: | FileCheck %s --check-prefix=RV64IBT
11 declare i32 @llvm.abs.i32(i32, i1 immarg)
12 declare i64 @llvm.abs.i64(i64, i1 immarg)
14 define i32 @neg_abs32(i32 %x) {
15 ; RV32I-LABEL: neg_abs32:
17 ; RV32I-NEXT: srai a1, a0, 31
18 ; RV32I-NEXT: xor a0, a0, a1
19 ; RV32I-NEXT: sub a0, a1, a0
22 ; RV32IBT-LABEL: neg_abs32:
24 ; RV32IBT-NEXT: srai a1, a0, 31
25 ; RV32IBT-NEXT: xor a0, a0, a1
26 ; RV32IBT-NEXT: sub a0, a1, a0
29 ; RV64I-LABEL: neg_abs32:
31 ; RV64I-NEXT: sraiw a1, a0, 31
32 ; RV64I-NEXT: xor a0, a0, a1
33 ; RV64I-NEXT: subw a0, a1, a0
36 ; RV64IBT-LABEL: neg_abs32:
38 ; RV64IBT-NEXT: sraiw a1, a0, 31
39 ; RV64IBT-NEXT: xor a0, a0, a1
40 ; RV64IBT-NEXT: subw a0, a1, a0
42 %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true)
43 %neg = sub nsw i32 0, %abs
47 define i32 @select_neg_abs32(i32 %x) {
48 ; RV32I-LABEL: select_neg_abs32:
50 ; RV32I-NEXT: srai a1, a0, 31
51 ; RV32I-NEXT: xor a0, a0, a1
52 ; RV32I-NEXT: sub a0, a1, a0
55 ; RV32IBT-LABEL: select_neg_abs32:
57 ; RV32IBT-NEXT: srai a1, a0, 31
58 ; RV32IBT-NEXT: xor a0, a0, a1
59 ; RV32IBT-NEXT: sub a0, a1, a0
62 ; RV64I-LABEL: select_neg_abs32:
64 ; RV64I-NEXT: sraiw a1, a0, 31
65 ; RV64I-NEXT: xor a0, a0, a1
66 ; RV64I-NEXT: subw a0, a1, a0
69 ; RV64IBT-LABEL: select_neg_abs32:
71 ; RV64IBT-NEXT: sraiw a1, a0, 31
72 ; RV64IBT-NEXT: xor a0, a0, a1
73 ; RV64IBT-NEXT: subw a0, a1, a0
75 %1 = icmp slt i32 %x, 0
76 %2 = sub nsw i32 0, %x
77 %3 = select i1 %1, i32 %x, i32 %2
81 define i64 @neg_abs64(i64 %x) {
82 ; RV32I-LABEL: neg_abs64:
84 ; RV32I-NEXT: srai a2, a1, 31
85 ; RV32I-NEXT: xor a0, a0, a2
86 ; RV32I-NEXT: sltu a3, a2, a0
87 ; RV32I-NEXT: xor a1, a1, a2
88 ; RV32I-NEXT: sub a1, a2, a1
89 ; RV32I-NEXT: sub a1, a1, a3
90 ; RV32I-NEXT: sub a0, a2, a0
93 ; RV32IBT-LABEL: neg_abs64:
95 ; RV32IBT-NEXT: srai a2, a1, 31
96 ; RV32IBT-NEXT: xor a0, a0, a2
97 ; RV32IBT-NEXT: sltu a3, a2, a0
98 ; RV32IBT-NEXT: xor a1, a1, a2
99 ; RV32IBT-NEXT: sub a1, a2, a1
100 ; RV32IBT-NEXT: sub a1, a1, a3
101 ; RV32IBT-NEXT: sub a0, a2, a0
104 ; RV64I-LABEL: neg_abs64:
106 ; RV64I-NEXT: srai a1, a0, 63
107 ; RV64I-NEXT: xor a0, a0, a1
108 ; RV64I-NEXT: sub a0, a1, a0
111 ; RV64IBT-LABEL: neg_abs64:
113 ; RV64IBT-NEXT: srai a1, a0, 63
114 ; RV64IBT-NEXT: xor a0, a0, a1
115 ; RV64IBT-NEXT: sub a0, a1, a0
117 %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
118 %neg = sub nsw i64 0, %abs
122 define i64 @select_neg_abs64(i64 %x) {
123 ; RV32I-LABEL: select_neg_abs64:
125 ; RV32I-NEXT: srai a2, a1, 31
126 ; RV32I-NEXT: xor a0, a0, a2
127 ; RV32I-NEXT: sltu a3, a2, a0
128 ; RV32I-NEXT: xor a1, a1, a2
129 ; RV32I-NEXT: sub a1, a2, a1
130 ; RV32I-NEXT: sub a1, a1, a3
131 ; RV32I-NEXT: sub a0, a2, a0
134 ; RV32IBT-LABEL: select_neg_abs64:
136 ; RV32IBT-NEXT: srai a2, a1, 31
137 ; RV32IBT-NEXT: xor a0, a0, a2
138 ; RV32IBT-NEXT: sltu a3, a2, a0
139 ; RV32IBT-NEXT: xor a1, a1, a2
140 ; RV32IBT-NEXT: sub a1, a2, a1
141 ; RV32IBT-NEXT: sub a1, a1, a3
142 ; RV32IBT-NEXT: sub a0, a2, a0
145 ; RV64I-LABEL: select_neg_abs64:
147 ; RV64I-NEXT: srai a1, a0, 63
148 ; RV64I-NEXT: xor a0, a0, a1
149 ; RV64I-NEXT: sub a0, a1, a0
152 ; RV64IBT-LABEL: select_neg_abs64:
154 ; RV64IBT-NEXT: srai a1, a0, 63
155 ; RV64IBT-NEXT: xor a0, a0, a1
156 ; RV64IBT-NEXT: sub a0, a1, a0
158 %1 = icmp slt i64 %x, 0
159 %2 = sub nsw i64 0, %x
160 %3 = select i1 %1, i64 %x, i64 %2