aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorVyacheslav Levytskyy <vyacheslav.levytskyy@intel.com>2024-06-26 19:38:51 +0200
committerGitHub <noreply@github.com>2024-06-26 19:38:51 +0200
commit0d9172ecaca2b0834e65343aa24d7cfa4f6d841d (patch)
tree32d75d01308c74ddd02e2e23304b102b4abb1c79 /llvm/lib
parent581fd2fa573e39607ea164c0b4a8057baeb62c69 (diff)
downloadllvm-0d9172ecaca2b0834e65343aa24d7cfa4f6d841d.zip
llvm-0d9172ecaca2b0834e65343aa24d7cfa4f6d841d.tar.gz
llvm-0d9172ecaca2b0834e65343aa24d7cfa4f6d841d.tar.bz2
[SPIR-V] Improve pattern matching and tracking of constant integers (#96615)
This PR fixes the issue https://github.com/llvm/llvm-project/issues/96614 by improve pattern matching and tracking of constant integers. The attached test is successful if it doesn't crash and generate valid SPIR-V code for both 32 and 64 bits targets.
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp13
-rw-r--r--llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp26
2 files changed, 31 insertions, 8 deletions
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index f5b6bcd..9be736c 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -1802,15 +1802,18 @@ bool SPIRVInstructionSelector::selectOpUndef(Register ResVReg,
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI) {
assert(MO.isReg());
const SPIRVType *TypeInst = MRI->getVRegDef(MO.getReg());
- if (TypeInst->getOpcode() != SPIRV::ASSIGN_TYPE)
- return false;
- assert(TypeInst->getOperand(1).isReg());
- MachineInstr *ImmInst = MRI->getVRegDef(TypeInst->getOperand(1).getReg());
- return ImmInst->getOpcode() == TargetOpcode::G_CONSTANT;
+ if (TypeInst->getOpcode() == SPIRV::ASSIGN_TYPE) {
+ assert(TypeInst->getOperand(1).isReg());
+ MachineInstr *ImmInst = MRI->getVRegDef(TypeInst->getOperand(1).getReg());
+ return ImmInst->getOpcode() == TargetOpcode::G_CONSTANT;
+ }
+ return TypeInst->getOpcode() == SPIRV::OpConstantI;
}
static int64_t foldImm(const MachineOperand &MO, MachineRegisterInfo *MRI) {
const SPIRVType *TypeInst = MRI->getVRegDef(MO.getReg());
+ if (TypeInst->getOpcode() == SPIRV::OpConstantI)
+ return TypeInst->getOperand(2).getImm();
MachineInstr *ImmInst = MRI->getVRegDef(TypeInst->getOperand(1).getReg());
assert(ImmInst->getOpcode() == TargetOpcode::G_CONSTANT);
return ImmInst->getOperand(1).getCImm()->getZExtValue();
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 2df96c4..0ea2f17 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -415,6 +415,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
MachineRegisterInfo &MRI = MF.getRegInfo();
SmallVector<MachineInstr *, 10> ToErase;
+ DenseMap<MachineInstr *, Register> RegsAlreadyAddedToDT;
for (MachineBasicBlock *MBB : post_order(&MF)) {
if (MBB->empty())
@@ -466,6 +467,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
// %rctmp = G_CONSTANT ty Val
// %rc = ASSIGN_TYPE %rctmp, %cty
Register Reg = MI.getOperand(0).getReg();
+ bool NeedAssignType = true;
if (MRI.hasOneUse(Reg)) {
MachineInstr &UseMI = *MRI.use_instr_begin(Reg);
if (isSpvIntrinsic(UseMI, Intrinsic::spv_assign_type) ||
@@ -478,7 +480,20 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
Ty = TargetExtIt == TargetExtConstTypes.end()
? MI.getOperand(1).getCImm()->getType()
: TargetExtIt->second;
- GR->add(MI.getOperand(1).getCImm(), &MF, Reg);
+ const ConstantInt *OpCI = MI.getOperand(1).getCImm();
+ Register PrimaryReg = GR->find(OpCI, &MF);
+ if (!PrimaryReg.isValid()) {
+ GR->add(OpCI, &MF, Reg);
+ } else if (PrimaryReg != Reg &&
+ MRI.getType(Reg) == MRI.getType(PrimaryReg)) {
+ auto *RCReg = MRI.getRegClassOrNull(Reg);
+ auto *RCPrimary = MRI.getRegClassOrNull(PrimaryReg);
+ if (!RCReg || RCPrimary == RCReg) {
+ RegsAlreadyAddedToDT[&MI] = PrimaryReg;
+ ToErase.push_back(&MI);
+ NeedAssignType = false;
+ }
+ }
} else if (MIOp == TargetOpcode::G_FCONSTANT) {
Ty = MI.getOperand(1).getFPImm()->getType();
} else {
@@ -497,7 +512,8 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
MI.getNumExplicitOperands() - MI.getNumExplicitDefs();
Ty = VectorType::get(ElemTy, NumElts, false);
}
- insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MRI);
+ if (NeedAssignType)
+ insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MRI);
} else if (MIOp == TargetOpcode::G_GLOBAL_VALUE) {
propagateSPIRVType(&MI, GR, MRI, MIB);
}
@@ -508,8 +524,12 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
--MII;
}
}
- for (MachineInstr *MI : ToErase)
+ for (MachineInstr *MI : ToErase) {
+ auto It = RegsAlreadyAddedToDT.find(MI);
+ if (RegsAlreadyAddedToDT.contains(MI))
+ MRI.replaceRegWith(MI->getOperand(0).getReg(), It->second);
MI->eraseFromParent();
+ }
// Address the case when IRTranslator introduces instructions with new
// registers without SPIRVType associated.