aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorVyacheslav Levytskyy <89994100+VyacheslavLevytskyy@users.noreply.github.com>2024-02-27 10:58:04 +0100
committerGitHub <noreply@github.com>2024-02-27 10:58:04 +0100
commit9796b0e9f91bc8ff00d2616fa3656e1ca848c05c (patch)
tree2f3e1beb0c59ac4e7e1da1b2aedd05c491763ca2 /llvm/lib
parent288d317fff42b46151b132ca2bdc4b0ca6d28d6f (diff)
downloadllvm-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.cpp44
-rw-r--r--llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp2
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);