Skip to content

Commit 5deb787

Browse files
authored
[RISCV][GISel] Add manual instruction selection for i8/i16/i32->i32/i64 G_SEXT/G_ZEXT. (#161971)
Because GISel doesn't distinquish integer and FP types, we need to allow s16/s32 as legal inputs/outputs of G_SEXT and G_ZEXT. This requires a extra isel patterns to support the cross product of these types that we don't need for SelectionDAG. We also needed to add i16/i32 to the GPR register class which prevents some type inferencing in tablegen and increases the size of the RISCVGenDAGISel.inc by 2K. This patch proposes to do manual selection so we can remove these patterns and eventually remove the types from the register class.
1 parent e5d15c1 commit 5deb787

File tree

2 files changed

+56
-54
lines changed

2 files changed

+56
-54
lines changed

llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,62 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
736736
MI.eraseFromParent();
737737
return true;
738738
}
739+
case TargetOpcode::G_ZEXT:
740+
case TargetOpcode::G_SEXT: {
741+
bool IsSigned = Opc != TargetOpcode::G_ZEXT;
742+
Register DstReg = MI.getOperand(0).getReg();
743+
Register SrcReg = MI.getOperand(1).getReg();
744+
LLT SrcTy = MRI->getType(SrcReg);
745+
unsigned SrcSize = SrcTy.getSizeInBits();
746+
747+
if (SrcTy.isVector())
748+
return false; // Should be handled by imported patterns.
749+
750+
assert((*RBI.getRegBank(DstReg, *MRI, TRI)).getID() ==
751+
RISCV::GPRBRegBankID &&
752+
"Unexpected ext regbank");
753+
754+
// Use addiw SrcReg, 0 (sext.w) for i32.
755+
if (IsSigned && SrcSize == 32) {
756+
MI.setDesc(TII.get(RISCV::ADDIW));
757+
MI.addOperand(MachineOperand::CreateImm(0));
758+
return constrainSelectedInstRegOperands(MI, TII, TRI, RBI);
759+
}
760+
761+
// Use add.uw SrcReg, X0 (zext.w) for i32 with Zba.
762+
if (!IsSigned && SrcSize == 32 && STI.hasStdExtZba()) {
763+
MI.setDesc(TII.get(RISCV::ADD_UW));
764+
MI.addOperand(MachineOperand::CreateReg(RISCV::X0, /*isDef=*/false));
765+
return constrainSelectedInstRegOperands(MI, TII, TRI, RBI);
766+
}
767+
768+
// Use sext.h/zext.h for i16 with Zbb.
769+
if (SrcSize == 16 && STI.hasStdExtZbb()) {
770+
MI.setDesc(TII.get(IsSigned ? RISCV::SEXT_H
771+
: STI.isRV64() ? RISCV::ZEXT_H_RV64
772+
: RISCV::ZEXT_H_RV32));
773+
return constrainSelectedInstRegOperands(MI, TII, TRI, RBI);
774+
}
775+
776+
// Use pack(w) SrcReg, X0 for i16 zext with Zbkb.
777+
if (!IsSigned && SrcSize == 16 && STI.hasStdExtZbkb()) {
778+
MI.setDesc(TII.get(STI.is64Bit() ? RISCV::PACKW : RISCV::PACK));
779+
MI.addOperand(MachineOperand::CreateReg(RISCV::X0, /*isDef=*/false));
780+
return constrainSelectedInstRegOperands(MI, TII, TRI, RBI);
781+
}
782+
783+
// Fall back to shift pair.
784+
auto ShiftLeft =
785+
MIB.buildInstr(RISCV::SLLI, {&RISCV::GPRRegClass}, {SrcReg})
786+
.addImm(STI.getXLen() - SrcSize);
787+
constrainSelectedInstRegOperands(*ShiftLeft, TII, TRI, RBI);
788+
auto ShiftRight = MIB.buildInstr(IsSigned ? RISCV::SRAI : RISCV::SRLI,
789+
{DstReg}, {ShiftLeft})
790+
.addImm(STI.getXLen() - SrcSize);
791+
constrainSelectedInstRegOperands(*ShiftRight, TII, TRI, RBI);
792+
MI.eraseFromParent();
793+
return true;
794+
}
739795
case TargetOpcode::G_FCONSTANT: {
740796
// TODO: Use constant pool for complex constants.
741797
Register DstReg = MI.getOperand(0).getReg();

llvm/lib/Target/RISCV/RISCVGISel.td

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -133,64 +133,10 @@ def : LdPat<extloadi16, LH, i32>;
133133
def : StPat<truncstorei8, SB, GPR, i32>;
134134
def : StPat<truncstorei16, SH, GPR, i32>;
135135

136-
def : Pat<(sext (i32 GPR:$src)), (ADDIW GPR:$src, 0)>;
137-
138136
def : Pat<(sext_inreg (i64 (add GPR:$rs1, simm12_lo:$imm)), i32),
139137
(ADDIW GPR:$rs1, simm12_lo:$imm)>;
140138
}
141139

142-
let Predicates = [IsRV64, NoStdExtZba] in
143-
def : Pat<(zext (i32 GPR:$src)), (SRLI (i64 (SLLI GPR:$src, 32)), 32)>;
144-
145-
let Predicates = [IsRV32, NoStdExtZbb, NoStdExtZbkb] in
146-
def : Pat<(XLenVT (zext (i16 GPR:$src))),
147-
(SRLI (XLenVT (SLLI GPR:$src, 16)), 16)>;
148-
149-
let Predicates = [IsRV64, NoStdExtZbb, NoStdExtZbkb] in {
150-
def : Pat<(i64 (zext (i16 GPR:$src))),
151-
(SRLI (XLenVT (SLLI GPR:$src, 48)), 48)>;
152-
def : Pat<(i32 (zext (i16 GPR:$src))),
153-
(SRLI (XLenVT (SLLI GPR:$src, 48)), 48)>;
154-
}
155-
156-
let Predicates = [IsRV32, NoStdExtZbb] in
157-
def : Pat<(XLenVT (sext (i16 GPR:$src))),
158-
(SRAI (XLenVT (SLLI GPR:$src, 16)), 16)>;
159-
160-
let Predicates = [IsRV64, NoStdExtZbb] in {
161-
def : Pat<(i64 (sext (i16 GPR:$src))),
162-
(SRAI (XLenVT (SLLI GPR:$src, 48)), 48)>;
163-
def : Pat<(i32 (sext (i16 GPR:$src))),
164-
(SRAI (XLenVT (SLLI GPR:$src, 48)), 48)>;
165-
}
166-
167-
//===----------------------------------------------------------------------===//
168-
// Zb* RV64 patterns not used by SelectionDAG.
169-
//===----------------------------------------------------------------------===//
170-
171-
let Predicates = [HasStdExtZba, IsRV64] in {
172-
def : Pat<(zext (i32 GPR:$src)), (ADD_UW GPR:$src, (XLenVT X0))>;
173-
}
174-
175-
let Predicates = [HasStdExtZbb] in
176-
def : Pat<(i32 (sext (i16 GPR:$rs))), (SEXT_H GPR:$rs)>;
177-
let Predicates = [HasStdExtZbb, IsRV64] in
178-
def : Pat<(i64 (sext (i16 GPR:$rs))), (SEXT_H GPR:$rs)>;
179-
180-
let Predicates = [HasStdExtZbb, IsRV32] in
181-
def : Pat<(i32 (zext (i16 GPR:$rs))), (ZEXT_H_RV32 GPR:$rs)>;
182-
let Predicates = [HasStdExtZbb, IsRV64] in {
183-
def : Pat<(i64 (zext (i16 GPR:$rs))), (ZEXT_H_RV64 GPR:$rs)>;
184-
def : Pat<(i32 (zext (i16 GPR:$rs))), (ZEXT_H_RV64 GPR:$rs)>;
185-
}
186-
187-
let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV32] in
188-
def : Pat<(i32 (zext (i16 GPR:$rs))), (PACK GPR:$rs, (XLenVT X0))>;
189-
let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64] in {
190-
def : Pat<(i64 (zext (i16 GPR:$rs))), (PACKW GPR:$rs, (XLenVT X0))>;
191-
def : Pat<(i32 (zext (i16 GPR:$rs))), (PACKW GPR:$rs, (XLenVT X0))>;
192-
}
193-
194140
//===----------------------------------------------------------------------===//
195141
// Zalasr patterns not used by SelectionDAG
196142
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)