Skip to content

Commit 31daed8

Browse files
authored
[RISCV] Prefer QC_EXTU to ANDI for certain 12-bit mask immediates (#143838)
`QC_EXTU` can be compressed to `QC_C_EXTU` when the immediate is a `mask >=63`. We currently only handle masks that don't fit in 12-bits in `RISCVISelDAGToDAG`. I have added ISEL patterns in `RISCVInstrInfoXqci.td` instead of changing code in `RISCVISelDAGToDAG` since the other extract instructions ( in `XTHeadbb` and `XAndesPerf`) don't have compressed versions and it is a lot easier to maintain things this way.
1 parent 56548e1 commit 31daed8

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,14 @@ let Predicates = [HasVendorXqcibm, IsRV32] in {
14411441
def : Pat<(sext_inreg (i32 GPR:$rs1), i16), (QC_EXT GPR:$rs1, 16, 0)>;
14421442
def : Pat<(sext_inreg (i32 GPR:$rs1), i8), (QC_EXT GPR:$rs1, 8, 0)>;
14431443
def : Pat<(sext_inreg (i32 GPR:$rs1), i1), (QC_EXT GPR:$rs1, 1, 0)>;
1444+
1445+
// Prefer qc.extu to andi for the following cases since the former can be compressed
1446+
def : Pat<(i32 (and GPRNoX0:$rs, 63)), (QC_EXTU GPRNoX0:$rs, 6, 0)>;
1447+
def : Pat<(i32 (and GPRNoX0:$rs, 127)), (QC_EXTU GPRNoX0:$rs, 7, 0)>;
1448+
def : Pat<(i32 (and GPRNoX0:$rs, 255)), (QC_EXTU GPRNoX0:$rs, 8, 0)>;
1449+
def : Pat<(i32 (and GPRNoX0:$rs, 511)), (QC_EXTU GPRNoX0:$rs, 9, 0)>;
1450+
def : Pat<(i32 (and GPRNoX0:$rs, 1023)), (QC_EXTU GPRNoX0:$rs, 10, 0)>;
1451+
def : Pat<(i32 (and GPRNoX0:$rs, 2047)), (QC_EXTU GPRNoX0:$rs, 11, 0)>;
14441452
} // Predicates = [HasVendorXqcibm, IsRV32]
14451453

14461454
let Predicates = [HasVendorXqciint, IsRV32] in

llvm/test/CodeGen/RISCV/xqcibm-extract.ll

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,48 @@ define i32 @extu_from_and_i32(i32 %x) {
247247
ret i32 %a
248248
}
249249

250+
define i32 @no_extu_from_and_i32(i32 %x) {
251+
; RV32I-LABEL: no_extu_from_and_i32:
252+
; RV32I: # %bb.0:
253+
; RV32I-NEXT: andi a0, a0, 31
254+
; RV32I-NEXT: ret
255+
;
256+
; RV32XQCIBM-LABEL: no_extu_from_and_i32:
257+
; RV32XQCIBM: # %bb.0:
258+
; RV32XQCIBM-NEXT: andi a0, a0, 31
259+
; RV32XQCIBM-NEXT: ret
260+
%a = and i32 %x, 31
261+
ret i32 %a
262+
}
263+
264+
define i32 @extu_from_and_i32_simm12_lb(i32 %x) {
265+
; RV32I-LABEL: extu_from_and_i32_simm12_lb:
266+
; RV32I: # %bb.0:
267+
; RV32I-NEXT: andi a0, a0, 63
268+
; RV32I-NEXT: ret
269+
;
270+
; RV32XQCIBM-LABEL: extu_from_and_i32_simm12_lb:
271+
; RV32XQCIBM: # %bb.0:
272+
; RV32XQCIBM-NEXT: qc.extu a0, a0, 6, 0
273+
; RV32XQCIBM-NEXT: ret
274+
%a = and i32 %x, 63
275+
ret i32 %a
276+
}
277+
278+
define i32 @extu_from_and_i32_simm12_ub(i32 %x) {
279+
; RV32I-LABEL: extu_from_and_i32_simm12_ub:
280+
; RV32I: # %bb.0:
281+
; RV32I-NEXT: andi a0, a0, 2047
282+
; RV32I-NEXT: ret
283+
;
284+
; RV32XQCIBM-LABEL: extu_from_and_i32_simm12_ub:
285+
; RV32XQCIBM: # %bb.0:
286+
; RV32XQCIBM-NEXT: qc.extu a0, a0, 11, 0
287+
; RV32XQCIBM-NEXT: ret
288+
%a = and i32 %x, 2047
289+
ret i32 %a
290+
}
291+
250292
define i64 @extu_from_and_i64(i64 %x) {
251293
; RV32I-LABEL: extu_from_and_i64:
252294
; RV32I: # %bb.0:

0 commit comments

Comments
 (0)