Skip to content

Commit 6c1a607

Browse files
[RISCV][GISEL] Legalize G_ZEXT, G_SEXT, and G_ANYEXT for scalable vector types
1 parent 2b6c038 commit 6c1a607

File tree

5 files changed

+3730
-3
lines changed

5 files changed

+3730
-3
lines changed

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

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,17 +139,23 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
139139
.clampScalar(0, s32, sXLen)
140140
.minScalarSameAs(1, 0);
141141

142+
auto &ExtActions =
143+
getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
144+
.legalIf(all(typeIsLegalIntOrFPVec(0, IntOrFPVecTys, ST),
145+
typeIsLegalIntOrFPVec(1, IntOrFPVecTys, ST)));
146+
142147
if (ST.is64Bit()) {
143-
getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
144-
.legalFor({{sXLen, s32}})
148+
ExtActions.legalFor({{sXLen, s32}})
149+
.customIf(typeIsLegalBoolVec(1, BoolVecTys, ST))
145150
.maxScalar(0, sXLen);
146151

147152
getActionDefinitionsBuilder(G_SEXT_INREG)
148153
.customFor({sXLen})
149154
.maxScalar(0, sXLen)
150155
.lower();
151156
} else {
152-
getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT}).maxScalar(0, sXLen);
157+
ExtActions.customIf(typeIsLegalBoolVec(1, BoolVecTys, ST))
158+
.maxScalar(0, sXLen);
153159

154160
getActionDefinitionsBuilder(G_SEXT_INREG).maxScalar(0, sXLen).lower();
155161
}
@@ -570,6 +576,33 @@ bool RISCVLegalizerInfo::legalizeVScale(MachineInstr &MI,
570576
auto VScale = MIB.buildLShr(XLenTy, VLENB, MIB.buildConstant(XLenTy, 3));
571577
MIB.buildMul(Dst, VScale, MIB.buildConstant(XLenTy, Val));
572578
}
579+
MI.eraseFromParent();
580+
return true;
581+
}
582+
583+
// Custom-lower extensions from mask vectors by using a vselect either with 1
584+
// for zero/any-extension or -1 for sign-extension:
585+
// (vXiN = (s|z)ext vXi1:vmask) -> (vXiN = vselect vmask, (-1 or 1), 0)
586+
// Note that any-extension is lowered identically to zero-extension.
587+
bool RISCVLegalizerInfo::legalizeExt(MachineInstr &MI,
588+
MachineIRBuilder &MIB) const {
589+
590+
unsigned Opc = MI.getOpcode();
591+
assert(Opc == TargetOpcode::G_ZEXT || Opc == TargetOpcode::G_SEXT ||
592+
Opc == TargetOpcode::G_ANYEXT);
593+
594+
MachineRegisterInfo &MRI = *MIB.getMRI();
595+
Register Dst = MI.getOperand(0).getReg();
596+
Register Src = MI.getOperand(1).getReg();
597+
598+
LLT DstTy = MRI.getType(Dst);
599+
int64_t ExtTrueVal =
600+
Opc == TargetOpcode::G_ZEXT || Opc == TargetOpcode::G_ANYEXT ? 1 : -1;
601+
LLT DstEltTy = DstTy.getElementType();
602+
auto SplatZero = MIB.buildSplatVector(DstTy, MIB.buildConstant(DstEltTy, 0));
603+
auto SplatTrue =
604+
MIB.buildSplatVector(DstTy, MIB.buildConstant(DstEltTy, ExtTrueVal));
605+
MIB.buildSelect(Dst, Src, SplatTrue, SplatZero);
573606

574607
MI.eraseFromParent();
575608
return true;
@@ -634,6 +667,10 @@ bool RISCVLegalizerInfo::legalizeCustom(
634667
return legalizeVAStart(MI, MIRBuilder);
635668
case TargetOpcode::G_VSCALE:
636669
return legalizeVScale(MI, MIRBuilder);
670+
case TargetOpcode::G_ZEXT:
671+
case TargetOpcode::G_SEXT:
672+
case TargetOpcode::G_ANYEXT:
673+
return legalizeExt(MI, MIRBuilder);
637674
}
638675

639676
llvm_unreachable("expected switch to return");

llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class RISCVLegalizerInfo : public LegalizerInfo {
4343

4444
bool legalizeVAStart(MachineInstr &MI, MachineIRBuilder &MIRBuilder) const;
4545
bool legalizeVScale(MachineInstr &MI, MachineIRBuilder &MIB) const;
46+
bool legalizeExt(MachineInstr &MI, MachineIRBuilder &MIRBuilder) const;
4647
};
4748
} // end namespace llvm
4849
#endif

0 commit comments

Comments
 (0)