Skip to content

Commit 14693ad

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

File tree

5 files changed

+3728
-6
lines changed

5 files changed

+3728
-6
lines changed

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

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,20 +139,21 @@ 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)));
142146
if (ST.is64Bit()) {
143-
getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
144-
.legalFor({{sXLen, s32}})
145-
.maxScalar(0, sXLen);
146-
147+
ExtActions.legalFor({{sXLen, s32}});
147148
getActionDefinitionsBuilder(G_SEXT_INREG)
148149
.customFor({sXLen})
149150
.maxScalar(0, sXLen)
150151
.lower();
151152
} else {
152-
getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT}).maxScalar(0, sXLen);
153-
154153
getActionDefinitionsBuilder(G_SEXT_INREG).maxScalar(0, sXLen).lower();
155154
}
155+
ExtActions.customIf(typeIsLegalBoolVec(1, BoolVecTys, ST))
156+
.maxScalar(0, sXLen);
156157

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

574602
MI.eraseFromParent();
575603
return true;
@@ -634,6 +662,10 @@ bool RISCVLegalizerInfo::legalizeCustom(
634662
return legalizeVAStart(MI, MIRBuilder);
635663
case TargetOpcode::G_VSCALE:
636664
return legalizeVScale(MI, MIRBuilder);
665+
case TargetOpcode::G_ZEXT:
666+
case TargetOpcode::G_SEXT:
667+
case TargetOpcode::G_ANYEXT:
668+
return legalizeExt(MI, MIRBuilder);
637669
}
638670

639671
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)