1 ; This test is designed to run 4 times, once with function attribute +c,
2 ; once with function attribute -c for eq/ne in icmp
3 ; The optimization should appear only with +c, otherwise default isel should be
6 ; RUN: cat %s | sed 's/CMPCOND/eq/g' | sed 's/RESBRNORMAL/bne/g' | \
7 ; RUN: sed 's/RESBROPT/c.bnez/g' > %t.compress_eq
8 ; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=+c,+f,+d -filetype=obj \
9 ; RUN: -disable-block-placement < %t.compress_eq \
10 ; RUN: | llvm-objdump -d --triple=riscv32 --mattr=+c,+f,+d -M no-aliases - \
11 ; RUN: | FileCheck -check-prefix=RV32IFDC %t.compress_eq
13 ; RUN: cat %s | sed -e 's/CMPCOND/eq/g' | sed -e 's/RESBRNORMAL/bne/g'\
14 ; RUN: | sed -e 's/RESBROPT/c.bnez/g' > %t.nocompr_eq
15 ; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=-c,+f,+d -filetype=obj \
16 ; RUN: -disable-block-placement < %t.nocompr_eq \
17 ; RUN: | llvm-objdump -d --triple=riscv32 --mattr=-c,+f,+d -M no-aliases - \
18 ; RUN: | FileCheck -check-prefix=RV32IFD %t.nocompr_eq
20 ; RUN: cat %s | sed 's/CMPCOND/ne/g' | sed 's/RESBRNORMAL/beq/g' | \
21 ; RUN: sed 's/RESBROPT/c.beqz/g' > %t.compress_neq
22 ; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=+c,+f,+d -filetype=obj \
23 ; RUN: -disable-block-placement < %t.compress_neq \
24 ; RUN: | llvm-objdump -d --triple=riscv32 --mattr=+c,+f,+d -M no-aliases - \
25 ; RUN: | FileCheck -check-prefix=RV32IFDC %t.compress_neq
27 ; RUN: cat %s | sed -e 's/CMPCOND/ne/g' | sed -e 's/RESBRNORMAL/beq/g'\
28 ; RUN: | sed -e 's/RESBROPT/c.beqz/g' > %t.nocompr_neq
29 ; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=-c,+f,+d -filetype=obj \
30 ; RUN: -disable-block-placement < %t.nocompr_neq \
31 ; RUN: | llvm-objdump -d --triple=riscv32 --mattr=-c,+f,+d -M no-aliases - \
32 ; RUN: | FileCheck -check-prefix=RV32IFD %t.nocompr_neq
35 ; constant is small and fit in 6 bit (compress imm)
36 ; RV32IFDC-LABEL: <f_small_pos>:
37 ; RV32IFDC: c.li [[REG:.*]], 0x14
38 ; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
39 ; --- no compress extension
40 ; RV32IFD-LABEL: <f_small_pos>:
41 ; RV32IFD: addi [[REG:.*]], zero, 0x14
42 ; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
43 define i32 @f_small_pos(i32 %in0) minsize {
44 %cmp = icmp CMPCOND i32 %in0, 20
45 br i1 %cmp, label %if.then, label %if.else
47 %call = shl i32 %in0, 1
50 %call2 = add i32 %in0, 42
54 %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
58 ; constant is small and fit in 6 bit (compress imm)
59 ; RV32IFDC-LABEL: <f_small_neg>:
60 ; RV32IFDC: c.li [[REG:.*]], -0x14
61 ; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
62 ; --- no compress extension
63 ; RV32IFD-LABEL: <f_small_neg>:
64 ; RV32IFD: addi [[REG:.*]], zero, -0x14
65 ; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
66 define i32 @f_small_neg(i32 %in0) minsize {
67 %cmp = icmp CMPCOND i32 %in0, -20
68 br i1 %cmp, label %if.then, label %if.else
70 %call = shl i32 %in0, 1
73 %call2 = add i32 %in0, 42
77 %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
81 ; constant is small and fit in 6 bit (compress imm)
82 ; RV32IFDC-LABEL: <f_small_edge_pos>:
83 ; RV32IFDC: c.li [[REG:.*]], 0x1f
84 ; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
85 ; --- no compress extension
86 ; RV32IFD-LABEL: <f_small_edge_pos>:
87 ; RV32IFD: addi [[REG:.*]], zero, 0x1f
88 ; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
89 define i32 @f_small_edge_pos(i32 %in0) minsize {
90 %cmp = icmp CMPCOND i32 %in0, 31
91 br i1 %cmp, label %if.then, label %if.else
93 %call = shl i32 %in0, 1
96 %call2 = add i32 %in0, 42
100 %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
104 ; constant is small and fit in 6 bit (compress imm)
105 ; RV32IFDC-LABEL: <f_small_edge_neg>:
106 ; RV32IFDC: c.li [[REG:.*]], -0x20
107 ; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
108 ; --- no compress extension
109 ; RV32IFD-LABEL: <f_small_edge_neg>:
110 ; RV32IFD: addi [[REG:.*]], zero, -0x20
111 ; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
112 define i32 @f_small_edge_neg(i32 %in0) minsize {
113 %cmp = icmp CMPCOND i32 %in0, -32
114 br i1 %cmp, label %if.then, label %if.else
116 %call = shl i32 %in0, 1
119 %call2 = add i32 %in0, 42
123 %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
127 ; constant is medium and not fit in 6 bit (compress imm),
128 ; but fit in 12 bit (imm)
129 ; RV32IFDC-LABEL: <f_medium_ledge_pos>:
130 ; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], -0x20
131 ; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
132 ; --- no compress extension
133 ; RV32IFD-LABEL: <f_medium_ledge_pos>:
134 ; RV32IFD: addi [[REG:.*]], zero, 0x20
135 ; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
136 define i32 @f_medium_ledge_pos(i32 %in0) minsize {
137 %cmp = icmp CMPCOND i32 %in0, 32
138 br i1 %cmp, label %if.then, label %if.else
140 %call = shl i32 %in0, 1
143 %call2 = add i32 %in0, 42
147 %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
151 ; constant is medium and not fit in 6 bit (compress imm),
152 ; but fit in 12 bit (imm)
153 ; RV32IFDC-LABEL: <f_medium_ledge_neg>:
154 ; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], 0x21
155 ; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
156 ; --- no compress extension
157 ; RV32IFD-LABEL: <f_medium_ledge_neg>:
158 ; RV32IFD: addi [[REG:.*]], zero, -0x21
159 ; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
160 define i32 @f_medium_ledge_neg(i32 %in0) minsize {
161 %cmp = icmp CMPCOND i32 %in0, -33
162 br i1 %cmp, label %if.then, label %if.else
164 %call = shl i32 %in0, 1
167 %call2 = add i32 %in0, 42
171 %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
175 ; constant is medium and not fit in 6 bit (compress imm),
176 ; but fit in 12 bit (imm)
177 ; RV32IFDC-LABEL: <f_medium_pos>:
178 ; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], -0x3f
179 ; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
180 ; --- no compress extension
181 ; RV32IFD-LABEL: <f_medium_pos>:
182 ; RV32IFD: addi [[REG:.*]], zero, 0x3f
183 ; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
184 define i32 @f_medium_pos(i32 %in0) minsize {
185 %cmp = icmp CMPCOND i32 %in0, 63
186 br i1 %cmp, label %if.then, label %if.else
188 %call = shl i32 %in0, 1
191 %call2 = add i32 %in0, 42
195 %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
199 ; constant is medium and not fit in 6 bit (compress imm),
200 ; but fit in 12 bit (imm)
201 ; RV32IFDC-LABEL: <f_medium_neg>:
202 ; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], 0x3f
203 ; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
204 ; --- no compress extension
205 ; RV32IFD-LABEL: <f_medium_neg>:
206 ; RV32IFD: addi [[REG:.*]], zero, -0x3f
207 ; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
208 define i32 @f_medium_neg(i32 %in0) minsize {
209 %cmp = icmp CMPCOND i32 %in0, -63
210 br i1 %cmp, label %if.then, label %if.else
212 %call = shl i32 %in0, 1
215 %call2 = add i32 %in0, 42
219 %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
223 ; constant is medium and not fit in 6 bit (compress imm),
224 ; but fit in 12 bit (imm)
225 ; RV32IFDC-LABEL: <f_medium_bedge_pos>:
226 ; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], -0x7ff
227 ; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
228 ; --- no compress extension
229 ; RV32IFD-LABEL: <f_medium_bedge_pos>:
230 ; RV32IFD: addi [[REG:.*]], zero, 0x7ff
231 ; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
232 define i32 @f_medium_bedge_pos(i32 %in0) minsize {
233 %cmp = icmp CMPCOND i32 %in0, 2047
234 br i1 %cmp, label %if.then, label %if.else
236 %call = shl i32 %in0, 1
239 %call2 = add i32 %in0, 42
243 %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
247 ; constant is medium and not fit in 6 bit (compress imm),
248 ; but fit in 12 bit (imm), negative value fit in 12 bit too.
249 ; RV32IFDC-LABEL: <f_medium_bedge_neg>:
250 ; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], 0x7ff
251 ; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
252 ; --- no compress extension
253 ; RV32IFD-LABEL: <f_medium_bedge_neg>:
254 ; RV32IFD: addi [[REG:.*]], zero, -0x7ff
255 ; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
256 define i32 @f_medium_bedge_neg(i32 %in0) minsize {
257 %cmp = icmp CMPCOND i32 %in0, -2047
258 br i1 %cmp, label %if.then, label %if.else
260 %call = shl i32 %in0, 1
263 %call2 = add i32 %in0, 42
267 %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
271 ; constant is big and do not fit in 12 bit (imm), fit in i32
272 ; RV32IFDC-LABEL: <f_big_ledge_pos>:
273 ; RV32IFDC-NOT: RESBROPT
274 ; --- no compress extension
276 define i32 @f_big_ledge_pos(i32 %in0) minsize {
277 %cmp = icmp CMPCOND i32 %in0, 2048
278 br i1 %cmp, label %if.then, label %if.else
280 %call = shl i32 %in0, 1
283 %call2 = add i32 %in0, 42
287 %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
291 ; constant is big and do not fit in 12 bit (imm), fit in i32
292 ; RV32IFDC-LABEL: <f_big_ledge_neg>:
293 ; RV32IFDC-NOT: c.beqz
294 ; --- no compress extension
296 define i32 @f_big_ledge_neg(i32 %in0) minsize {
297 %cmp = icmp CMPCOND i32 %in0, -2048
298 br i1 %cmp, label %if.then, label %if.else
300 %call = shl i32 %in0, 1
303 %call2 = add i32 %in0, 42
307 %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]