diff options
author | Vyacheslav Levytskyy <89994100+VyacheslavLevytskyy@users.noreply.github.com> | 2024-02-27 10:58:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-27 10:58:04 +0100 |
commit | 9796b0e9f91bc8ff00d2616fa3656e1ca848c05c (patch) | |
tree | 2f3e1beb0c59ac4e7e1da1b2aedd05c491763ca2 /llvm/lib | |
parent | 288d317fff42b46151b132ca2bdc4b0ca6d28d6f (diff) | |
download | llvm-9796b0e9f91bc8ff00d2616fa3656e1ca848c05c.zip llvm-9796b0e9f91bc8ff00d2616fa3656e1ca848c05c.tar.gz llvm-9796b0e9f91bc8ff00d2616fa3656e1ca848c05c.tar.bz2 |
Add support for the 'freeze' instruction (#82979)
This PR is to add support for the 'freeze' instruction:
https://llvm.org/docs/LangRef.html#freeze-instruction
There is no way to implement `freeze` correctly without support on
SPIR-V standard side, but we may at least address a simple (static) case
when undef/poison value presence is obvious. The main benefit of even
incomplete `freeze` support is preventing of translation from crashing
due to lack of support on legalization and instruction selection steps.
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp | 44 | ||||
-rw-r--r-- | llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 2 |
2 files changed, 45 insertions, 1 deletions
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 7258d3b..f1e18f0 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -150,6 +150,8 @@ private: bool selectOpUndef(Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const; + bool selectFreeze(Register ResVReg, const SPIRVType *ResType, + MachineInstr &I) const; bool selectIntrinsic(Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const; bool selectExtractVal(Register ResVReg, const SPIRVType *ResType, @@ -284,6 +286,8 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg, return selectGlobalValue(ResVReg, I); case TargetOpcode::G_IMPLICIT_DEF: return selectOpUndef(ResVReg, ResType, I); + case TargetOpcode::G_FREEZE: + return selectFreeze(ResVReg, ResType, I); case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS: case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS: @@ -1014,6 +1018,46 @@ bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg, .constrainAllUses(TII, TRI, RBI); } +bool SPIRVInstructionSelector::selectFreeze(Register ResVReg, + const SPIRVType *ResType, + MachineInstr &I) const { + // There is no way to implement `freeze` correctly without support on SPIR-V + // standard side, but we may at least address a simple (static) case when + // undef/poison value presence is obvious. The main benefit of even + // incomplete `freeze` support is preventing of translation from crashing due + // to lack of support on legalization and instruction selection steps. + if (!I.getOperand(0).isReg() || !I.getOperand(1).isReg()) + return false; + Register OpReg = I.getOperand(1).getReg(); + if (MachineInstr *Def = MRI->getVRegDef(OpReg)) { + Register Reg; + switch (Def->getOpcode()) { + case SPIRV::ASSIGN_TYPE: + if (MachineInstr *AssignToDef = + MRI->getVRegDef(Def->getOperand(1).getReg())) { + if (AssignToDef->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) + Reg = Def->getOperand(2).getReg(); + } + break; + case SPIRV::OpUndef: + Reg = Def->getOperand(1).getReg(); + break; + } + unsigned DestOpCode; + if (Reg.isValid()) { + DestOpCode = SPIRV::OpConstantNull; + } else { + DestOpCode = TargetOpcode::COPY; + Reg = OpReg; + } + return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(DestOpCode)) + .addDef(I.getOperand(0).getReg()) + .addUse(Reg) + .constrainAllUses(TII, TRI, RBI); + } + return false; +} + bool SPIRVInstructionSelector::selectConstVector(Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const { diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp index 4f2e7a2..aedca79 100644 --- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp @@ -184,7 +184,7 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) { return Query.Types[0].getSizeInBits() == Query.Types[1].getSizeInBits(); })))); - getActionDefinitionsBuilder(G_IMPLICIT_DEF).alwaysLegal(); + getActionDefinitionsBuilder({G_IMPLICIT_DEF, G_FREEZE}).alwaysLegal(); getActionDefinitionsBuilder(G_INTTOPTR) .legalForCartesianProduct(allPtrs, allIntScalars); |