[llvm] [RISCV][GISEL] Legalize, regbank select, and instruction select G_ZEXT, G_SEXT, and G_ANYEXT (PR #85938)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 20 07:22:03 PDT 2024
- Previous message: [llvm] [RISCV][GISEL] Legalize, regbank select, and instruction select G_ZEXT, G_SEXT, and G_ANYEXT (PR #85938)
- Next message: [llvm] [RISCV][GISEL] Legalize, regbank select, and instruction select G_ZEXT, G_SEXT, G_ANYEXT, G_SPLAT_VECTOR, and G_ICMP (PR #85938)
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
Author: Michael Maitland (michaelmaitland)
<details>
<summary>Changes</summary>
This PR is stacked on #<!-- -->84553 and #<!-- -->84553. This PR contains a series of multiple commits which I did not break up into their own separate PRs since there are cyclical dependencies between them. I explain these dependencies below.
19733ebdc0c17d8e3a37408a7d5a6a32eee427d3, 72c4b54ee58feb49e872203696da2731abf59a85, and 05d463b0ca140ba9618cb01cef66e174eb959ea1 do legalization, regbankselect, and instruction-selection for G_ZEXT, G_SEXT, and G_ANYEXT with scalable vector type.
However, legalization of s1 element vectors for G_ZEXT, G_SEXT, and G_ANYEXT build G_SPLAT_VECTOR and G_SELECT instructions. As a result, we legalize G_SPLAT vector in 12402d8d52aea744f6c3b599955e5370125b719b and G_SELECT in #<!-- -->85540.
Legalization of G_SPLAT_VECTOR relies on building a G_ICMP where the true and false values are s1. As a result, we include 41bef89c86a3fabe97c947870e138dfc6fc0bfc6, 88c7cfd5f35173f24914dc2ae106c31a8f0a26ab and 0125e1c3f165fb746c0d1ce5a0ea468d31986391 to do legalization, regbankselect, and instruction selection for G_ICMP.
I wanted to have G_ICMP work as its own PR, but since the true and false values are s1 element vectors, the legalization depends on sign extension, creating a cyclic dependency between these patches.
---
Patch is 424.63 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/85938.diff
25 Files Affected:
- (modified) llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp (+2-1)
- (modified) llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (+1-1)
- (modified) llvm/lib/CodeGen/LowLevelTypeUtils.cpp (+1-1)
- (modified) llvm/lib/CodeGen/MachineVerifier.cpp (+2-1)
- (modified) llvm/lib/CodeGen/RegisterBankInfo.cpp (+4-3)
- (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp (+139-5)
- (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h (+2)
- (modified) llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp (+17-5)
- (modified) llvm/lib/Target/RISCV/RISCVInstrGISel.td (+16)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/anyext.mir (+704)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/icmp.mir (+534)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/sext.mir (+340)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/zext.mir (+704)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rvv/legalize-anyext.mir (+761)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rvv/legalize-icmp.mir (+468)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rvv/legalize-sext.mir (+811)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rvv/legalize-splatvector-rv32.mir (+734)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rvv/legalize-splatvector-rv64.mir (+566)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rvv/legalize-zext.mir (+811)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/rvv/anyext.mir (+1115)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/rvv/icmp.mir (+675)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/rvv/sext.mir (+1115)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/rvv/zext.mir (+1115)
- (modified) llvm/test/MachineVerifier/test_g_fcmp.mir (+6-1)
- (modified) llvm/test/MachineVerifier/test_g_icmp.mir (+6-1)
``````````diff
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
index 4ee1793d33d2ca..c9ee35373cd445 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
@@ -154,7 +154,8 @@ static bool mutationIsSane(const LegalizeRule &Rule,
case WidenScalar: {
if (OldTy.isVector()) {
// Number of elements should not change.
- if (!NewTy.isVector() || OldTy.getNumElements() != NewTy.getNumElements())
+ if (!NewTy.isVector() ||
+ OldTy.getElementCount() != NewTy.getElementCount())
return false;
} else {
// Both types must be vectors
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index f7aaa0f02efcb3..01d32d20a63dbc 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -1153,7 +1153,7 @@ void MachineIRBuilder::validateSelectOp(const LLT ResTy, const LLT TstTy,
else
assert((TstTy.isScalar() ||
(TstTy.isVector() &&
- TstTy.getNumElements() == Op0Ty.getNumElements())) &&
+ TstTy.getElementCount() == Op0Ty.getElementCount())) &&
"type mismatch");
#endif
}
diff --git a/llvm/lib/CodeGen/LowLevelTypeUtils.cpp b/llvm/lib/CodeGen/LowLevelTypeUtils.cpp
index 5caf20add2a11e..1602cd99c383c6 100644
--- a/llvm/lib/CodeGen/LowLevelTypeUtils.cpp
+++ b/llvm/lib/CodeGen/LowLevelTypeUtils.cpp
@@ -51,7 +51,7 @@ MVT llvm::getMVTForLLT(LLT Ty) {
return MVT::getVectorVT(
MVT::getIntegerVT(Ty.getElementType().getSizeInBits()),
- Ty.getNumElements());
+ Ty.getElementCount());
}
EVT llvm::getApproximateEVTForLLT(LLT Ty, const DataLayout &DL,
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index c69d36fc7fdd60..16bbd33ce7134e 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -1506,7 +1506,8 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
LLT SrcTy = MRI->getType(MI->getOperand(2).getReg());
if ((DstTy.isVector() != SrcTy.isVector()) ||
- (DstTy.isVector() && DstTy.getNumElements() != SrcTy.getNumElements()))
+ (DstTy.isVector() &&
+ DstTy.getElementCount() != SrcTy.getElementCount()))
report("Generic vector icmp/fcmp must preserve number of lanes", MI);
break;
diff --git a/llvm/lib/CodeGen/RegisterBankInfo.cpp b/llvm/lib/CodeGen/RegisterBankInfo.cpp
index 5548430d1b0ae8..72b07eb1902d9b 100644
--- a/llvm/lib/CodeGen/RegisterBankInfo.cpp
+++ b/llvm/lib/CodeGen/RegisterBankInfo.cpp
@@ -484,9 +484,10 @@ void RegisterBankInfo::applyDefaultMapping(const OperandsMapper &OpdMapper) {
// the storage. However, right now we don't necessarily bump all
// the types to storage size. For instance, we can consider
// s16 G_AND legal whereas the storage size is going to be 32.
- assert(OrigTy.getSizeInBits() <= NewTy.getSizeInBits() &&
- "Types with difference size cannot be handled by the default "
- "mapping");
+ assert(
+ TypeSize::isKnownLE(OrigTy.getSizeInBits(), NewTy.getSizeInBits()) &&
+ "Types with difference size cannot be handled by the default "
+ "mapping");
LLVM_DEBUG(dbgs() << "\nChange type of new opd from " << NewTy << " to "
<< OrigTy);
MRI.setType(NewReg, OrigTy);
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 64ae4e94a8c929..0725a9c1da6104 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -111,18 +111,20 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
.clampScalar(0, s32, sXLen)
.minScalarSameAs(1, 0);
+ auto &ExtActions =
+ getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
+ .customIf(typeIsLegalBoolVec(1, BoolVecTys, ST))
+ .legalIf(all(typeIsLegalIntOrFPVec(0, IntOrFPVecTys, ST),
+ typeIsLegalIntOrFPVec(1, IntOrFPVecTys, ST)))
+ .maxScalar(0, sXLen);
if (ST.is64Bit()) {
- getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
- .legalFor({{sXLen, s32}})
- .maxScalar(0, sXLen);
+ ExtActions.legalFor({{sXLen, s32}});
getActionDefinitionsBuilder(G_SEXT_INREG)
.customFor({sXLen})
.maxScalar(0, sXLen)
.lower();
} else {
- getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT}).maxScalar(0, sXLen);
-
getActionDefinitionsBuilder(G_SEXT_INREG).maxScalar(0, sXLen).lower();
}
@@ -198,6 +200,9 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
getActionDefinitionsBuilder(G_ICMP)
.legalFor({{sXLen, sXLen}, {sXLen, p0}})
+ .widenScalarOrEltToNextPow2OrMinSize(1, 8)
+ .legalIf(all(typeIsLegalBoolVec(0, BoolVecTys, ST),
+ typeIsLegalIntOrFPVec(1, IntOrFPVecTys, ST)))
.widenScalarToNextPow2(1)
.clampScalar(1, sXLen, sXLen)
.clampScalar(0, sXLen, sXLen);
@@ -374,6 +379,11 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
.clampScalar(0, s32, sXLen)
.lowerForCartesianProduct({s32, sXLen, p0}, {p0});
+ getActionDefinitionsBuilder(G_SPLAT_VECTOR)
+ .legalIf(all(typeIsLegalIntOrFPVec(0, IntOrFPVecTys, ST),
+ typeInSet(1, {s8, s16, s32, sXLen})))
+ .customIf(all(typeIsLegalBoolVec(0, BoolVecTys, ST), typeInSet(1, {s1})));
+
getLegacyLegalizerInfo().computeTables();
}
@@ -495,6 +505,124 @@ bool RISCVLegalizerInfo::shouldBeInConstantPool(APInt APImm,
return !(!SeqLo.empty() && (SeqLo.size() + 2) <= STI.getMaxBuildIntsCost());
}
+// Custom-lower extensions from mask vectors by using a vselect either with 1
+// for zero/any-extension or -1 for sign-extension:
+// (vXiN = (s|z)ext vXi1:vmask) -> (vXiN = vselect vmask, (-1 or 1), 0)
+// Note that any-extension is lowered identically to zero-extension.
+bool RISCVLegalizerInfo::legalizeExt(MachineInstr &MI,
+ MachineIRBuilder &MIB) const {
+
+ unsigned Opc = MI.getOpcode();
+ assert(Opc == TargetOpcode::G_ZEXT || Opc == TargetOpcode::G_SEXT ||
+ Opc == TargetOpcode::G_ANYEXT);
+
+ MachineRegisterInfo &MRI = *MIB.getMRI();
+ Register Dst = MI.getOperand(0).getReg();
+ Register Src = MI.getOperand(1).getReg();
+
+ LLT DstTy = MRI.getType(Dst);
+ LLT SrcTy = MRI.getType(Src);
+
+ // The only custom legalization of extends we handle are vector extends.
+ if (!DstTy.isVector() || !SrcTy.isVector())
+ return false;
+
+ // The only custom legalization of extends is from mask types
+ if (SrcTy.getElementType().getSizeInBits() != 1)
+ return false;
+
+ int64_t ExtTrueVal =
+ Opc == TargetOpcode::G_ZEXT || Opc == TargetOpcode::G_ANYEXT ? 1 : -1;
+ LLT DstEltTy = DstTy.getElementType();
+ auto SplatZero = MIB.buildSplatVector(DstTy, MIB.buildConstant(DstEltTy, 0));
+ auto SplatTrue =
+ MIB.buildSplatVector(DstTy, MIB.buildConstant(DstEltTy, ExtTrueVal));
+ MIB.buildSelect(Dst, Src, SplatTrue, SplatZero);
+ MI.eraseFromParent();
+ return true;
+}
+
+/// Return the type of the mask type suitable for masking the provided
+/// vector type. This is simply an i1 element type vector of the same
+/// (possibly scalable) length.
+static LLT getMaskTypeFor(LLT VecTy) {
+ assert(VecTy.isVector());
+ ElementCount EC = VecTy.getElementCount();
+ return LLT::vector(EC, LLT::scalar(1));
+}
+
+/// Creates an all ones mask suitable for masking a vector of type VecTy with
+/// vector length VL.
+static MachineInstrBuilder buildAllOnesMask(LLT VecTy, const SrcOp &VL,
+ MachineIRBuilder &MIB,
+ MachineRegisterInfo &MRI) {
+ LLT MaskTy = getMaskTypeFor(VecTy);
+ return MIB.buildInstr(RISCV::G_VMSET_VL, {MaskTy}, {VL});
+}
+
+/// Gets the two common "VL" operands: an all-ones mask and the vector length.
+/// VecTy is a scalable vector type.
+static std::pair<MachineInstrBuilder, Register>
+buildDefaultVLOps(const DstOp &Dst, MachineIRBuilder &MIB,
+ MachineRegisterInfo &MRI) {
+ LLT VecTy = Dst.getLLTTy(MRI);
+ assert(VecTy.isScalableVector() && "Expecting scalable container type");
+ Register VL(RISCV::X0);
+ MachineInstrBuilder Mask = buildAllOnesMask(VecTy, VL, MIB, MRI);
+ return {Mask, VL};
+}
+
+// Lower splats of s1 types to G_ICMP. For each mask vector type, we have a
+// legal equivalently-sized i8 type, so we can use that as a go-between.
+// Splats of s1 types that have constant value can be legalized as VMSET_VL or
+// VMCLR_VL.
+bool RISCVLegalizerInfo::legalizeSplatVector(MachineInstr &MI,
+ MachineIRBuilder &MIB) const {
+ assert(MI.getOpcode() == TargetOpcode::G_SPLAT_VECTOR);
+
+ MachineRegisterInfo &MRI = *MIB.getMRI();
+
+ Register Dst = MI.getOperand(0).getReg();
+ Register SplatVal = MI.getOperand(1).getReg();
+
+ LLT VecTy = MRI.getType(Dst);
+ LLT SplatTy = MRI.getType(SplatVal);
+
+ // We should not see any splats on sizes larger than s1 since those are legal
+ // and do not need custom legalization.
+ if (SplatTy.getSizeInBits() != 1)
+ return false;
+
+ // All-zeros or all-ones splats are handled specially.
+ MachineInstr &SplatValMI = *MRI.getVRegDef(SplatVal);
+ if (isAllOnesOrAllOnesSplat(SplatValMI, MRI)) {
+ auto VL = buildDefaultVLOps(VecTy, MIB, MRI).second;
+ MIB.buildInstr(RISCV::G_VMSET_VL, {Dst}, {VL});
+ MI.eraseFromParent();
+ return true;
+ }
+ if (isNullOrNullSplat(SplatValMI, MRI)) {
+ auto VL = buildDefaultVLOps(VecTy, MIB, MRI).second;
+ MIB.buildInstr(RISCV::G_VMCLR_VL, {Dst}, {VL});
+ MI.eraseFromParent();
+ return true;
+ }
+
+ // Handle non-constant mask splat (i.e. not sure if it's all zeros or all
+ // ones) by promoting it to an s8 splat.
+ LLT InterEltTy = LLT::scalar(8);
+ LLT InterTy = VecTy.changeElementType(InterEltTy);
+ auto ZExtSplatVal = MIB.buildZExt(InterEltTy, SplatVal);
+ auto And =
+ MIB.buildAnd(InterEltTy, ZExtSplatVal, MIB.buildConstant(InterEltTy, 1));
+ auto LHS = MIB.buildSplatVector(InterTy, And);
+ auto ZeroSplat =
+ MIB.buildSplatVector(InterTy, MIB.buildConstant(InterEltTy, 0));
+ MIB.buildICmp(CmpInst::Predicate::ICMP_NE, Dst, LHS, ZeroSplat);
+ MI.eraseFromParent();
+ return true;
+}
+
bool RISCVLegalizerInfo::legalizeCustom(
LegalizerHelper &Helper, MachineInstr &MI,
LostDebugLocObserver &LocObserver) const {
@@ -552,6 +680,12 @@ bool RISCVLegalizerInfo::legalizeCustom(
}
case TargetOpcode::G_VASTART:
return legalizeVAStart(MI, MIRBuilder);
+ case TargetOpcode::G_ZEXT:
+ case TargetOpcode::G_SEXT:
+ case TargetOpcode::G_ANYEXT:
+ return legalizeExt(MI, MIRBuilder);
+ case TargetOpcode::G_SPLAT_VECTOR:
+ return legalizeSplatVector(MI, MIRBuilder);
}
llvm_unreachable("expected switch to return");
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h
index 323426034827e4..d0638b0daae408 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h
@@ -42,6 +42,8 @@ class RISCVLegalizerInfo : public LegalizerInfo {
GISelChangeObserver &Observer) const;
bool legalizeVAStart(MachineInstr &MI, MachineIRBuilder &MIRBuilder) const;
+ bool legalizeExt(MachineInstr &MI, MachineIRBuilder &MIRBuilder) const;
+ bool legalizeSplatVector(MachineInstr &MI, MachineIRBuilder &MIB) const;
};
} // end namespace llvm
#endif
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index 58c971aee2f4c8..8b93d19cdda999 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -289,7 +289,10 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
switch (Opc) {
case TargetOpcode::G_ADD:
- case TargetOpcode::G_SUB: {
+ case TargetOpcode::G_SUB:
+ case TargetOpcode::G_ANYEXT:
+ case TargetOpcode::G_SEXT:
+ case TargetOpcode::G_ZEXT: {
if (MRI.getType(MI.getOperand(0).getReg()).isVector()) {
LLT Ty = MRI.getType(MI.getOperand(0).getReg());
return getInstructionMapping(
@@ -297,8 +300,9 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
getVRBValueMapping(Ty.getSizeInBits().getKnownMinValue()),
NumOperands);
}
+ return getInstructionMapping(DefaultMappingID, /*Cost=*/1, GPRValueMapping,
+ NumOperands);
}
- LLVM_FALLTHROUGH;
case TargetOpcode::G_SHL:
case TargetOpcode::G_ASHR:
case TargetOpcode::G_LSHR:
@@ -320,9 +324,6 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case TargetOpcode::G_PTRTOINT:
case TargetOpcode::G_INTTOPTR:
case TargetOpcode::G_TRUNC:
- case TargetOpcode::G_ANYEXT:
- case TargetOpcode::G_SEXT:
- case TargetOpcode::G_ZEXT:
case TargetOpcode::G_SEXTLOAD:
case TargetOpcode::G_ZEXTLOAD:
return getInstructionMapping(DefaultMappingID, /*Cost=*/1, GPRValueMapping,
@@ -469,6 +470,17 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
OpdsMapping[1] = GPRValueMapping;
break;
}
+ case TargetOpcode::G_ICMP: {
+ if (MRI.getType(MI.getOperand(0).getReg()).isVector()) {
+ LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
+ LLT SrcTy = MRI.getType(MI.getOperand(2).getReg());
+ OpdsMapping[0] =
+ getVRBValueMapping(DstTy.getSizeInBits().getKnownMinValue());
+ OpdsMapping[2] = OpdsMapping[3] =
+ getVRBValueMapping(SrcTy.getSizeInBits().getKnownMinValue());
+ }
+ break;
+ }
case TargetOpcode::G_FCMP: {
LLT Ty = MRI.getType(MI.getOperand(2).getReg());
diff --git a/llvm/lib/Target/RISCV/RISCVInstrGISel.td b/llvm/lib/Target/RISCV/RISCVInstrGISel.td
index ede8c9809833cc..23b103726e3a4f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrGISel.td
@@ -24,3 +24,19 @@ def G_FCLASS : RISCVGenericInstruction {
let hasSideEffects = false;
}
def : GINodeEquiv<G_FCLASS, riscv_fclass>;
+
+// Pseudo equivalent to a RISCVISD::VMCLR_VL
+def G_VMCLR_VL : RISCVGenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$vl);
+ let hasSideEffects = false;
+}
+def : GINodeEquiv<G_VMCLR_VL, riscv_vmclr_vl>;
+
+// Pseudo equivalent to a RISCVISD::VMSET_VL
+def G_VMSET_VL : RISCVGenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$vl);
+ let hasSideEffects = false;
+}
+def : GINodeEquiv<G_VMSET_VL, riscv_vmset_vl>;
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/anyext.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/anyext.mir
new file mode 100644
index 00000000000000..0b99be67a8f0d1
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rvv/anyext.mir
@@ -0,0 +1,704 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+v -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - | FileCheck -check-prefix=RV32I %s
+# RUN: llc -mtriple=riscv64 -mattr=+v -run-pass=instruction-select -simplify-mir -verify-machineinstrs %s -o - | FileCheck -check-prefix=RV64I %s
+
+---
+name: anyext_nxv1i16_nxv1i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.0.entry:
+ ; RV32I-LABEL: name: anyext_nxv1i16_nxv1i8
+ ; RV32I: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV32I-NEXT: [[DEF1:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV32I-NEXT: early-clobber %1:vr = PseudoVZEXT_VF2_MF4 [[DEF1]], [[DEF]], -1, 4 /* e16 */, 3 /* ta, ma */
+ ; RV32I-NEXT: $v8 = COPY %1
+ ; RV32I-NEXT: PseudoRET implicit $v8
+ ;
+ ; RV64I-LABEL: name: anyext_nxv1i16_nxv1i8
+ ; RV64I: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV64I-NEXT: [[DEF1:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV64I-NEXT: early-clobber %1:vr = PseudoVZEXT_VF2_MF4 [[DEF1]], [[DEF]], -1, 4 /* e16 */, 3 /* ta, ma */
+ ; RV64I-NEXT: $v8 = COPY %1
+ ; RV64I-NEXT: PseudoRET implicit $v8
+ %0:vrb(<vscale x 1 x s8>) = G_IMPLICIT_DEF
+ %1:vrb(<vscale x 1 x s16>) = G_ANYEXT %0(<vscale x 1 x s8>)
+ $v8 = COPY %1(<vscale x 1 x s16>)
+ PseudoRET implicit $v8
+
+...
+---
+name: anyext_nxv1i32_nxv1i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.0.entry:
+ ; RV32I-LABEL: name: anyext_nxv1i32_nxv1i8
+ ; RV32I: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV32I-NEXT: [[DEF1:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV32I-NEXT: early-clobber %1:vr = PseudoVZEXT_VF4_MF2 [[DEF1]], [[DEF]], -1, 5 /* e32 */, 3 /* ta, ma */
+ ; RV32I-NEXT: $v8 = COPY %1
+ ; RV32I-NEXT: PseudoRET implicit $v8
+ ;
+ ; RV64I-LABEL: name: anyext_nxv1i32_nxv1i8
+ ; RV64I: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV64I-NEXT: [[DEF1:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV64I-NEXT: early-clobber %1:vr = PseudoVZEXT_VF4_MF2 [[DEF1]], [[DEF]], -1, 5 /* e32 */, 3 /* ta, ma */
+ ; RV64I-NEXT: $v8 = COPY %1
+ ; RV64I-NEXT: PseudoRET implicit $v8
+ %0:vrb(<vscale x 1 x s8>) = G_IMPLICIT_DEF
+ %1:vrb(<vscale x 1 x s32>) = G_ANYEXT %0(<vscale x 1 x s8>)
+ $v8 = COPY %1(<vscale x 1 x s32>)
+ PseudoRET implicit $v8
+
+...
+---
+name: anyext_nxv1i64_nxv1i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.0.entry:
+ ; RV32I-LABEL: name: anyext_nxv1i64_nxv1i8
+ ; RV32I: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV32I-NEXT: [[DEF1:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV32I-NEXT: early-clobber %1:vr = PseudoVZEXT_VF8_M1 [[DEF1]], [[DEF]], -1, 6 /* e64 */, 3 /* ta, ma */
+ ; RV32I-NEXT: $v8 = COPY %1
+ ; RV32I-NEXT: PseudoRET implicit $v8
+ ;
+ ; RV64I-LABEL: name: anyext_nxv1i64_nxv1i8
+ ; RV64I: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV64I-NEXT: [[DEF1:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV64I-NEXT: early-clobber %1:vr = PseudoVZEXT_VF8_M1 [[DEF1]], [[DEF]], -1, 6 /* e64 */, 3 /* ta, ma */
+ ; RV64I-NEXT: $v8 = COPY %1
+ ; RV64I-NEXT: PseudoRET implicit $v8
+ %0:vrb(<vscale x 1 x s8>) = G_IMPLICIT_DEF
+ %1:vrb(<vscale x 1 x s64>) = G_ANYEXT %0(<vscale x 1 x s8>)
+ $v8 = COPY %1(<vscale x 1 x s64>)
+ PseudoRET implicit $v8
+
+...
+---
+name: anyext_nxv2i16_nxv2i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.0.entry:
+ ; RV32I-LABEL: name: anyext_nxv2i16_nxv2i8
+ ; RV32I: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV32I-NEXT: [[DEF1:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV32I-NEXT: early-clobber %1:vr = PseudoVZEXT_VF2_MF2 [[DEF1]], [[DEF]], -1, 4 /* e16 */, 3 /* ta, ma */
+ ; RV32I-NEXT: $v8 = COPY %1
+ ; RV32I-NEXT: PseudoRET implicit $v8
+ ;
+ ; RV64I-LABEL: name: anyext_nxv2i16_nxv2i8
+ ; RV64I: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV64I-NEXT: [[DEF1:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV64I-NEXT: early-clobber %1:vr = PseudoVZEXT_VF2_MF2 [[DEF1]], [[DEF]], -1, 4 /* e16 */, 3 /* ta, ma */
+ ; RV64I-NEXT: $v8 = COPY %1
+ ; RV64I-NEXT: PseudoRET implicit $v8
+ %0:vrb(<vscale x 2 x s8>) = G_IMPLICIT_DEF
+ %1:vrb(<vscale x 2 x s16>) = G_ANYEXT %0(<vscale x 2 x s8>)
+ $v8 = COPY %1(<vscale x 2 x s16>)
+ PseudoRET implicit $v8
+
+...
+---
+name: anyext_nxv2i32_nxv2i8
+legalized: true
+regBankSelected: true
+body: |
+ bb.0.entry:
+ ; RV32I-LABEL: name: anyext_nxv2i32_nxv2i8
+ ; RV32I: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV32I-NEXT: [[DEF1:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV32I-NEXT: early-clobber %1:vr = PseudoVZEXT_VF4_M1 [[DEF1]], [[DEF]], -1, 5 /* e32 */, 3 /* ta, ma */
+ ; RV32I-NEXT: $v8 = COPY %1
+ ; RV32I-NEXT: PseudoRET implicit $v8
+ ;
+ ; RV64I-LABEL: name: anyext_nxv2i32_nxv2i8
+ ; RV64I: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV64I-NEXT: [[DEF1:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; RV64I-NEXT: early-clobber %1:vr = PseudoVZEXT_VF4_M1 [[DEF1]], [[DEF]], -1, 5 /* e32 */, 3 /* ta, ma */
+ ; RV64I-NEXT: $v8 = COPY %1
+ ; RV6...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/85938
- Previous message: [llvm] [RISCV][GISEL] Legalize, regbank select, and instruction select G_ZEXT, G_SEXT, and G_ANYEXT (PR #85938)
- Next message: [llvm] [RISCV][GISEL] Legalize, regbank select, and instruction select G_ZEXT, G_SEXT, G_ANYEXT, G_SPLAT_VECTOR, and G_ICMP (PR #85938)
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the llvm-commits
mailing list