[llvm] [SPIR-V] Rework duplicate tracker and tracking of IR entities and types (PR #130605)
Vyacheslav Levytskyy via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 17 14:22:48 PDT 2025
https://github.com/VyacheslavLevytskyy updated https://github.com/llvm/llvm-project/pull/130605
>From 33221a17e7e0d4a12249a248ccbbff0a7df02ae4 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 10 Mar 2025 06:46:43 -0700
Subject: [PATCH 01/12] remove spv_track_constant() intrnal intrinsics
---
llvm/include/llvm/IR/IntrinsicsSPIRV.td | 2 +-
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 9 +-
llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 82 ++++++++++---------
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 33 +++-----
llvm/lib/Target/SPIRV/SPIRVUtils.cpp | 19 ++---
5 files changed, 65 insertions(+), 80 deletions(-)
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 7012ef3534c68..89fb92be0e1eb 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -13,7 +13,7 @@
let TargetPrefix = "spv" in {
def int_spv_assign_type : Intrinsic<[], [llvm_any_ty, llvm_metadata_ty]>;
def int_spv_assign_ptr_type : Intrinsic<[], [llvm_any_ty, llvm_metadata_ty, llvm_i32_ty], [ImmArg<ArgIndex<2>>]>;
- def int_spv_assign_name : Intrinsic<[], [llvm_any_ty, llvm_vararg_ty]>;
+ def int_spv_assign_name : Intrinsic<[], [llvm_any_ty, llvm_metadata_ty]>;
def int_spv_assign_decoration : Intrinsic<[], [llvm_any_ty, llvm_metadata_ty]>;
def int_spv_value_md : Intrinsic<[], [llvm_metadata_ty]>;
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 579e37f68d5d8..f5c31ea737839 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -391,12 +391,9 @@ static MachineInstr *getBlockStructInstr(Register ParamReg,
// TODO: maybe unify with prelegalizer pass.
static unsigned getConstFromIntrinsic(Register Reg, MachineRegisterInfo *MRI) {
MachineInstr *DefMI = MRI->getUniqueVRegDef(Reg);
- assert(isSpvIntrinsic(*DefMI, Intrinsic::spv_track_constant) &&
- DefMI->getOperand(2).isReg());
- MachineInstr *DefMI2 = MRI->getUniqueVRegDef(DefMI->getOperand(2).getReg());
- assert(DefMI2->getOpcode() == TargetOpcode::G_CONSTANT &&
- DefMI2->getOperand(1).isCImm());
- return DefMI2->getOperand(1).getCImm()->getValue().getZExtValue();
+ assert(DefMI->getOpcode() == TargetOpcode::G_CONSTANT &&
+ DefMI->getOperand(1).isCImm());
+ return DefMI->getOperand(1).getCImm()->getValue().getZExtValue();
}
// Return type of the instruction result from spv_assign_type intrinsic.
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 751ea5ab2dc47..356f4f6dab75c 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -63,7 +63,7 @@ class SPIRVEmitIntrinsics
SPIRVTargetMachine *TM = nullptr;
SPIRVGlobalRegistry *GR = nullptr;
Function *CurrF = nullptr;
- bool TrackConstants = true;
+ bool TrackConstants = false;//true;
bool HaveFunPtrs = false;
DenseMap<Instruction *, Constant *> AggrConsts;
DenseMap<Instruction *, Type *> AggrConstTypes;
@@ -316,8 +316,10 @@ static void emitAssignName(Instruction *I, IRBuilder<> &B) {
return;
reportFatalOnTokenType(I);
setInsertPointAfterDef(B, I);
- std::vector<Value *> Args = {I};
- addStringImm(I->getName(), B, Args);
+ LLVMContext &Ctx = I->getContext();
+ std::vector<Value *> Args = {
+ I, MetadataAsValue::get(
+ Ctx, MDNode::get(Ctx, MDString::get(Ctx, I->getName())))};
B.CreateIntrinsic(Intrinsic::spv_assign_name, {I->getType()}, Args);
}
@@ -2023,7 +2025,7 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
auto *II = dyn_cast<IntrinsicInst>(I);
bool IsConstComposite =
II && II->getIntrinsicID() == Intrinsic::spv_const_composite;
- if (IsConstComposite && TrackConstants) {
+ if (IsConstComposite) {
setInsertPointAfterDef(B, I);
auto t = AggrConsts.find(I);
assert(t != AggrConsts.end());
@@ -2035,41 +2037,43 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
}
bool IsPhi = isa<PHINode>(I), BPrepared = false;
for (const auto &Op : I->operands()) {
- if (isa<PHINode>(I) || isa<SwitchInst>(I))
- TrackConstants = false;
- if ((isa<ConstantData>(Op) || isa<ConstantExpr>(Op)) && TrackConstants) {
- unsigned OpNo = Op.getOperandNo();
- if (II && ((II->getIntrinsicID() == Intrinsic::spv_gep && OpNo == 0) ||
- (II->paramHasAttr(OpNo, Attribute::ImmArg))))
- continue;
- if (!BPrepared) {
- IsPhi ? B.SetInsertPointPastAllocas(I->getParent()->getParent())
- : B.SetInsertPoint(I);
- BPrepared = true;
- }
- Type *OpTy = Op->getType();
- Value *OpTyVal = Op;
- if (OpTy->isTargetExtTy())
- OpTyVal = getNormalizedPoisonValue(OpTy);
- CallInst *NewOp =
- buildIntrWithMD(Intrinsic::spv_track_constant,
- {OpTy, OpTyVal->getType()}, Op, OpTyVal, {}, B);
- Type *OpElemTy = nullptr;
- if (!IsConstComposite && isPointerTy(OpTy) &&
- (OpElemTy = GR->findDeducedElementType(Op)) != nullptr &&
- OpElemTy != IntegerType::getInt8Ty(I->getContext())) {
- GR->buildAssignPtr(B, IntegerType::getInt8Ty(I->getContext()), NewOp);
- SmallVector<Type *, 2> Types = {OpTy, OpTy};
- SmallVector<Value *, 2> Args = {
- NewOp, buildMD(getNormalizedPoisonValue(OpElemTy)),
- B.getInt32(getPointerAddressSpace(OpTy))};
- CallInst *PtrCasted =
- B.CreateIntrinsic(Intrinsic::spv_ptrcast, {Types}, Args);
- GR->buildAssignPtr(B, OpElemTy, PtrCasted);
- NewOp = PtrCasted;
- }
- I->setOperand(OpNo, NewOp);
+ if (isa<PHINode>(I) || isa<SwitchInst>(I) ||
+ !(isa<ConstantData>(Op) || isa<ConstantExpr>(Op)))
+ continue;
+ unsigned OpNo = Op.getOperandNo();
+ if (II && ((II->getIntrinsicID() == Intrinsic::spv_gep && OpNo == 0) ||
+ (II->paramHasAttr(OpNo, Attribute::ImmArg))))
+ continue;
+
+ if (!BPrepared) {
+ IsPhi ? B.SetInsertPointPastAllocas(I->getParent()->getParent())
+ : B.SetInsertPoint(I);
+ BPrepared = true;
}
+ Type *OpTy = Op->getType();
+ Value *OpTyVal = Op;
+ if (OpTy->isTargetExtTy())
+ OpTyVal = getNormalizedPoisonValue(OpTy);
+ Value *NewOp = Op;
+ if (OpTy->isTargetExtTy())
+ NewOp = buildIntrWithMD(Intrinsic::spv_track_constant,
+ {OpTy, OpTyVal->getType()}, Op, OpTyVal, {}, B);
+ Type *OpElemTy = nullptr;
+ if (!IsConstComposite && isPointerTy(OpTy) &&
+ (OpElemTy = GR->findDeducedElementType(Op)) != nullptr &&
+ OpElemTy != IntegerType::getInt8Ty(I->getContext())) {
+ GR->buildAssignPtr(B, IntegerType::getInt8Ty(I->getContext()), NewOp);
+ SmallVector<Type *, 2> Types = {OpTy, OpTy};
+ SmallVector<Value *, 2> Args = {
+ NewOp, buildMD(getNormalizedPoisonValue(OpElemTy)),
+ B.getInt32(getPointerAddressSpace(OpTy))};
+ CallInst *PtrCasted =
+ B.CreateIntrinsic(Intrinsic::spv_ptrcast, {Types}, Args);
+ GR->buildAssignPtr(B, OpElemTy, PtrCasted);
+ NewOp = PtrCasted;
+ }
+ if (NewOp != Op)
+ I->setOperand(OpNo, NewOp);
}
emitAssignName(I, B);
}
@@ -2417,7 +2421,7 @@ bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) {
deduceOperandElementType(&Phi, nullptr);
for (auto *I : Worklist) {
- TrackConstants = true;
+ TrackConstants = false;//true;
if (!I->getType()->isVoidTy() || isa<StoreInst>(I))
setInsertPointAfterDef(B, I);
// Visitors return either the original/newly created instruction for further
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 3779a4b6ccd34..edf215f0ce00f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -133,32 +133,25 @@ addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
MI->eraseFromParent();
}
-static void
-foldConstantsIntoIntrinsics(MachineFunction &MF,
- const SmallSet<Register, 4> &TrackedConstRegs) {
- SmallVector<MachineInstr *, 10> ToErase;
- MachineRegisterInfo &MRI = MF.getRegInfo();
- const unsigned AssignNameOperandShift = 2;
+static void foldConstantsIntoIntrinsics(MachineFunction &MF,
+ MachineIRBuilder MIB) {
+ SmallVector<MachineInstr *, 64> ToErase;
for (MachineBasicBlock &MBB : MF) {
for (MachineInstr &MI : MBB) {
if (!isSpvIntrinsic(MI, Intrinsic::spv_assign_name))
continue;
- unsigned NumOp = MI.getNumExplicitDefs() + AssignNameOperandShift;
- while (MI.getOperand(NumOp).isReg()) {
- MachineOperand &MOp = MI.getOperand(NumOp);
- MachineInstr *ConstMI = MRI.getVRegDef(MOp.getReg());
- assert(ConstMI->getOpcode() == TargetOpcode::G_CONSTANT);
- MI.removeOperand(NumOp);
- MI.addOperand(MachineOperand::CreateImm(
- ConstMI->getOperand(1).getCImm()->getZExtValue()));
- Register DefReg = ConstMI->getOperand(0).getReg();
- if (MRI.use_empty(DefReg) && !TrackedConstRegs.contains(DefReg))
- ToErase.push_back(ConstMI);
+ const MDNode *MD = MI.getOperand(2).getMetadata();
+ StringRef ValueName = cast<MDString>(MD->getOperand(0))->getString();
+ if (ValueName.size() > 0) {
+ MIB.setInsertPt(*MI.getParent(), MI);
+ buildOpName(MI.getOperand(1).getReg(), ValueName, MIB);
}
+ ToErase.push_back(&MI);
}
+ for (MachineInstr *MI : ToErase)
+ MI->eraseFromParent();
+ ToErase.clear();
}
- for (MachineInstr *MI : ToErase)
- MI->eraseFromParent();
}
static MachineInstr *findAssignTypeInstr(Register Reg,
@@ -1043,7 +1036,7 @@ bool SPIRVPreLegalizer::runOnMachineFunction(MachineFunction &MF) {
// to keep record of tracked constants
SmallSet<Register, 4> TrackedConstRegs;
addConstantsToTrack(MF, GR, ST, TargetExtConstTypes, TrackedConstRegs);
- foldConstantsIntoIntrinsics(MF, TrackedConstRegs);
+ foldConstantsIntoIntrinsics(MF, MIB);
insertBitcasts(MF, GR, MIB);
generateAssignInstrs(MF, GR, MIB, TargetExtConstTypes);
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index ce4f6d6c9288f..05bebb5a0e9c1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -307,20 +307,11 @@ SPIRV::Scope::Scope getMemScope(LLVMContext &Ctx, SyncScope::ID Id) {
MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
const MachineRegisterInfo *MRI) {
MachineInstr *MI = MRI->getVRegDef(ConstReg);
- MachineInstr *ConstInstr =
- MI->getOpcode() == SPIRV::G_TRUNC || MI->getOpcode() == SPIRV::G_ZEXT
- ? MRI->getVRegDef(MI->getOperand(1).getReg())
- : MI;
- if (auto *GI = dyn_cast<GIntrinsic>(ConstInstr)) {
- if (GI->is(Intrinsic::spv_track_constant)) {
- ConstReg = ConstInstr->getOperand(2).getReg();
- return MRI->getVRegDef(ConstReg);
- }
- } else if (ConstInstr->getOpcode() == SPIRV::ASSIGN_TYPE) {
- ConstReg = ConstInstr->getOperand(1).getReg();
- return MRI->getVRegDef(ConstReg);
- }
- return MRI->getVRegDef(ConstReg);
+ if (MI->getOpcode() == SPIRV::G_TRUNC || MI->getOpcode() == SPIRV::G_ZEXT)
+ return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
+ if (MI->getOpcode() == SPIRV::ASSIGN_TYPE)
+ return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
+ return MI;
}
uint64_t getIConstVal(Register ConstReg, const MachineRegisterInfo *MRI) {
>From c2fcf6357b015fc1272d3658ca45db604fb9b19b Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 10 Mar 2025 11:39:29 -0700
Subject: [PATCH 02/12] fixes
---
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 5 ++-
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 29 ++++++++---------
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 3 +-
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 11 +++++++
llvm/lib/Target/SPIRV/SPIRVUtils.cpp | 32 +++++++++++++++++--
.../test/CodeGen/SPIRV/SampledImageRetType.ll | 6 ++--
6 files changed, 60 insertions(+), 26 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index f5c31ea737839..e6c0a526a9cec 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -1968,8 +1968,7 @@ static bool generateReadImageInst(const StringRef DemangledCall,
Sampler = GR->buildConstantSampler(
Register(), getSamplerAddressingModeFromBitmask(SamplerMask),
getSamplerParamFromBitmask(SamplerMask),
- getSamplerFilterModeFromBitmask(SamplerMask), MIRBuilder,
- GR->getSPIRVTypeForVReg(Sampler));
+ getSamplerFilterModeFromBitmask(SamplerMask), MIRBuilder);
}
SPIRVType *ImageType = GR->getSPIRVTypeForVReg(Image);
SPIRVType *SampledImageType =
@@ -2056,7 +2055,7 @@ static bool generateSampleImageInst(const StringRef DemangledCall,
Register Sampler = GR->buildConstantSampler(
Call->ReturnRegister, getSamplerAddressingModeFromBitmask(Bitmask),
getSamplerParamFromBitmask(Bitmask),
- getSamplerFilterModeFromBitmask(Bitmask), MIRBuilder, Call->ReturnType);
+ getSamplerFilterModeFromBitmask(Bitmask), MIRBuilder);
return Sampler.isValid();
} else if (Call->Builtin->Name.contains_insensitive("__spirv_SampledImage")) {
// Create OpSampledImage.
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index cbec1c95eadc3..fb718d9ddd0b4 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -398,7 +398,9 @@ Register SPIRVGlobalRegistry::buildConstantInt(uint64_t Val,
SPIRV::AccessQualifier::ReadWrite, EmitIR);
DT.add(ConstInt, &MIRBuilder.getMF(), Res);
if (EmitIR) {
- MIRBuilder.buildConstant(Res, *ConstInt);
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildConstant(Res, *ConstInt);
+ });
} else {
Register SpvTypeReg = getSPIRVTypeID(SpvType);
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
@@ -605,7 +607,9 @@ Register SPIRVGlobalRegistry::getOrCreateIntCompositeOrNull(
assignSPIRVTypeToVReg(SpvType, SpvVecConst, *CurMF);
DT.add(CA, CurMF, SpvVecConst);
if (EmitIR) {
- MIRBuilder.buildSplatBuildVector(SpvVecConst, SpvScalConst);
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildSplatBuildVector(SpvVecConst, SpvScalConst);
+ });
} else {
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
if (Val) {
@@ -668,17 +672,10 @@ SPIRVGlobalRegistry::getOrCreateConstNullPtr(MachineIRBuilder &MIRBuilder,
return Res;
}
-Register SPIRVGlobalRegistry::buildConstantSampler(
- Register ResReg, unsigned AddrMode, unsigned Param, unsigned FilerMode,
- MachineIRBuilder &MIRBuilder, SPIRVType *SpvType) {
- SPIRVType *SampTy;
- if (SpvType)
- SampTy = getOrCreateSPIRVType(getTypeForSPIRVType(SpvType), MIRBuilder,
- SPIRV::AccessQualifier::ReadWrite, true);
- else if ((SampTy = getOrCreateSPIRVTypeByName("opencl.sampler_t", MIRBuilder,
- false)) == nullptr)
- report_fatal_error("Unable to recognize SPIRV type name: opencl.sampler_t");
-
+Register
+SPIRVGlobalRegistry::buildConstantSampler(Register ResReg, unsigned AddrMode,
+ unsigned Param, unsigned FilerMode,
+ MachineIRBuilder &MIRBuilder) {
auto Sampler =
ResReg.isValid()
? ResReg
@@ -686,7 +683,7 @@ Register SPIRVGlobalRegistry::buildConstantSampler(
auto Res = createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
return MIRBuilder.buildInstr(SPIRV::OpConstantSampler)
.addDef(Sampler)
- .addUse(getSPIRVTypeID(SampTy))
+ .addUse(getSPIRVTypeID(getOrCreateOpTypeSampler(MIRBuilder)))
.addImm(AddrMode)
.addImm(Param)
.addImm(FilerMode);
@@ -1383,7 +1380,9 @@ SPIRVGlobalRegistry::getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder) {
return Res;
Register ResVReg = createTypeVReg(MIRBuilder);
DT.add(TD, &MIRBuilder.getMF(), ResVReg);
- return MIRBuilder.buildInstr(SPIRV::OpTypeSampler).addDef(ResVReg);
+ return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpTypeSampler).addDef(ResVReg);
+ });
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypePipe(
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 89599f17ef737..467d9b73e2e39 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -544,8 +544,7 @@ class SPIRVGlobalRegistry {
SPIRVType *SpvType);
Register buildConstantSampler(Register Res, unsigned AddrMode, unsigned Param,
unsigned FilerMode,
- MachineIRBuilder &MIRBuilder,
- SPIRVType *SpvType);
+ MachineIRBuilder &MIRBuilder);
Register getOrCreateUndef(MachineInstr &I, SPIRVType *SpvType,
const SPIRVInstrInfo &TII);
Register buildGlobalVariable(Register Reg, SPIRVType *BaseType,
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index b188f36ca9a9e..ce9ce3ef3135c 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2326,6 +2326,17 @@ static bool isConstReg(MachineRegisterInfo *MRI, SPIRVType *OpDef,
return false;
}
return true;
+ case SPIRV::OpConstantTrue:
+ case SPIRV::OpConstantFalse:
+ case SPIRV::OpConstantI:
+ case SPIRV::OpConstantF:
+ case SPIRV::OpConstantComposite:
+ case SPIRV::OpConstantCompositeContinuedINTEL:
+ case SPIRV::OpConstantSampler:
+ case SPIRV::OpConstantNull:
+ case SPIRV::OpUndef:
+ case SPIRV::OpConstantFunctionPointerINTEL:
+ return true;
}
}
return false;
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index 05bebb5a0e9c1..8380cd579004d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -303,16 +303,42 @@ SPIRV::Scope::Scope getMemScope(LLVMContext &Ctx, SyncScope::ID Id) {
return SPIRV::Scope::Device;
return SPIRV::Scope::CrossDevice;
}
-
+/*
MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
const MachineRegisterInfo *MRI) {
MachineInstr *MI = MRI->getVRegDef(ConstReg);
- if (MI->getOpcode() == SPIRV::G_TRUNC || MI->getOpcode() == SPIRV::G_ZEXT)
- return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
+ //if (MI->getOpcode() == SPIRV::G_TRUNC || MI->getOpcode() == SPIRV::G_ZEXT)
+ // return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
if (MI->getOpcode() == SPIRV::ASSIGN_TYPE)
return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
+ if (auto *GI = dyn_cast<GIntrinsic>(MI))
+ if (GI->is(Intrinsic::spv_track_constant))
+ return MRI->getVRegDef(ConstReg = MI->getOperand(2).getReg());
return MI;
}
+*/
+MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
+ const MachineRegisterInfo *MRI) {
+ MachineInstr *MI = MRI->getVRegDef(ConstReg);
+ MachineInstr *ConstInstr =
+ MI->getOpcode() == SPIRV::G_TRUNC || MI->getOpcode() == SPIRV::G_ZEXT
+ ? MRI->getVRegDef(MI->getOperand(1).getReg())
+ : MI;
+ if (auto *GI = dyn_cast<GIntrinsic>(ConstInstr)) {
+ if (GI->is(Intrinsic::spv_track_constant)) {
+ ConstReg = ConstInstr->getOperand(2).getReg();
+ return MRI->getVRegDef(ConstReg);
+ }
+ } else if (ConstInstr->getOpcode() == SPIRV::ASSIGN_TYPE) {
+ ConstReg = ConstInstr->getOperand(1).getReg();
+ return MRI->getVRegDef(ConstReg);
+ } else if (ConstInstr->getOpcode() == TargetOpcode::G_CONSTANT ||
+ ConstInstr->getOpcode() == TargetOpcode::G_FCONSTANT) {
+ ConstReg = ConstInstr->getOperand(0).getReg();
+ return ConstInstr;
+ }
+ return MRI->getVRegDef(ConstReg);
+}
uint64_t getIConstVal(Register ConstReg, const MachineRegisterInfo *MRI) {
const MachineInstr *MI = getDefInstrMaybeConstant(ConstReg, MRI);
diff --git a/llvm/test/CodeGen/SPIRV/SampledImageRetType.ll b/llvm/test/CodeGen/SPIRV/SampledImageRetType.ll
index f034f293dc6a9..91f83e09c94f0 100644
--- a/llvm/test/CodeGen/SPIRV/SampledImageRetType.ll
+++ b/llvm/test/CodeGen/SPIRV/SampledImageRetType.ll
@@ -4,9 +4,9 @@
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-; CHECK: %[[#image1d_t:]] = OpTypeImage
-; CHECK: %[[#sampler_t:]] = OpTypeSampler
-; CHECK: %[[#sampled_image_t:]] = OpTypeSampledImage
+; CHECK-DAG: %[[#image1d_t:]] = OpTypeImage
+; CHECK-DAG: %[[#sampler_t:]] = OpTypeSampler
+; CHECK-DAG: %[[#sampled_image_t:]] = OpTypeSampledImage
declare dso_local spir_func ptr addrspace(4) @_Z20__spirv_SampledImageI14ocl_image1d_roPvET0_T_11ocl_sampler(target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 0) %0, target("spirv.Sampler") %1) local_unnamed_addr
>From 663108c10f9fbd46075d1710dd0beb21a1918331 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Tue, 11 Mar 2025 04:44:05 -0700
Subject: [PATCH 03/12] remove duplicate tracker
---
.../lib/Target/SPIRV/SPIRVDuplicatesTracker.h | 228 ++++-----------
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 275 +++++++-----------
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 41 +--
3 files changed, 165 insertions(+), 379 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
index 441e32c1eb695..21e1069adb2d3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
+++ b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
@@ -26,35 +26,8 @@
namespace llvm {
namespace SPIRV {
-class SPIRVInstrInfo;
-// NOTE: using MapVector instead of DenseMap because it helps getting
-// everything ordered in a stable manner for a price of extra (NumKeys)*PtrSize
-// memory and expensive removals which do not happen anyway.
-class DTSortableEntry : public MapVector<const MachineFunction *, Register> {
- SmallVector<DTSortableEntry *, 2> Deps;
- struct FlagsTy {
- unsigned IsFunc : 1;
- unsigned IsGV : 1;
- unsigned IsConst : 1;
- // NOTE: bit-field default init is a C++20 feature.
- FlagsTy() : IsFunc(0), IsGV(0), IsConst(0) {}
- };
- FlagsTy Flags;
-
-public:
- // Common hoisting utility doesn't support function, because their hoisting
- // require hoisting of params as well.
- bool getIsFunc() const { return Flags.IsFunc; }
- bool getIsGV() const { return Flags.IsGV; }
- bool getIsConst() const { return Flags.IsConst; }
- void setIsFunc(bool V) { Flags.IsFunc = V; }
- void setIsGV(bool V) { Flags.IsGV = V; }
- void setIsConst(bool V) { Flags.IsConst = V; }
-
- const SmallVector<DTSortableEntry *, 2> &getDeps() const { return Deps; }
- void addDep(DTSortableEntry *E) { Deps.push_back(E); }
-};
+using IRHandle = std::tuple<const void *, unsigned, unsigned>;
enum SpecialTypeKind {
STK_Empty = 0,
@@ -63,12 +36,11 @@ enum SpecialTypeKind {
STK_Sampler,
STK_Pipe,
STK_DeviceEvent,
+ STK_ElementPointer,
STK_Pointer,
STK_Last = -1
};
-using SpecialTypeDescriptor = std::tuple<const Type *, unsigned, unsigned>;
-
union ImageAttrs {
struct BitFlags {
unsigned Dim : 3;
@@ -94,18 +66,18 @@ union ImageAttrs {
}
};
-inline SpecialTypeDescriptor
-make_descr_image(const Type *SampledTy, unsigned Dim, unsigned Depth,
- unsigned Arrayed, unsigned MS, unsigned Sampled,
- unsigned ImageFormat, unsigned AQ = 0) {
+inline IRHandle make_descr_image(const Type *SampledTy, unsigned Dim,
+ unsigned Depth, unsigned Arrayed, unsigned MS,
+ unsigned Sampled, unsigned ImageFormat,
+ unsigned AQ = 0) {
return std::make_tuple(
SampledTy,
ImageAttrs(Dim, Depth, Arrayed, MS, Sampled, ImageFormat, AQ).Val,
SpecialTypeKind::STK_Image);
}
-inline SpecialTypeDescriptor
-make_descr_sampled_image(const Type *SampledTy, const MachineInstr *ImageTy) {
+inline IRHandle make_descr_sampled_image(const Type *SampledTy,
+ const MachineInstr *ImageTy) {
assert(ImageTy->getOpcode() == SPIRV::OpTypeImage);
unsigned AC = AccessQualifier::AccessQualifier::None;
if (ImageTy->getNumOperands() > 8)
@@ -120,170 +92,84 @@ make_descr_sampled_image(const Type *SampledTy, const MachineInstr *ImageTy) {
SpecialTypeKind::STK_SampledImage);
}
-inline SpecialTypeDescriptor make_descr_sampler() {
+inline IRHandle make_descr_sampler() {
return std::make_tuple(nullptr, 0U, SpecialTypeKind::STK_Sampler);
}
-inline SpecialTypeDescriptor make_descr_pipe(uint8_t AQ) {
+inline IRHandle make_descr_pipe(uint8_t AQ) {
return std::make_tuple(nullptr, AQ, SpecialTypeKind::STK_Pipe);
}
-inline SpecialTypeDescriptor make_descr_event() {
+inline IRHandle make_descr_event() {
return std::make_tuple(nullptr, 0U, SpecialTypeKind::STK_DeviceEvent);
}
-inline SpecialTypeDescriptor make_descr_pointee(const Type *ElementType,
- unsigned AddressSpace) {
+inline IRHandle make_descr_pointee(const Type *ElementType,
+ unsigned AddressSpace) {
return std::make_tuple(ElementType, AddressSpace,
- SpecialTypeKind::STK_Pointer);
+ SpecialTypeKind::STK_ElementPointer);
}
-} // namespace SPIRV
-template <typename KeyTy> class SPIRVDuplicatesTrackerBase {
-public:
- // NOTE: using MapVector instead of DenseMap helps getting everything ordered
- // in a stable manner for a price of extra (NumKeys)*PtrSize memory and
- // expensive removals which don't happen anyway.
- using StorageTy = MapVector<KeyTy, SPIRV::DTSortableEntry>;
+inline IRHandle make_descr_ptr(const void *Ptr) {
+ return std::make_tuple(Ptr, 0U, SpecialTypeKind::STK_Pointer);
+}
+} // namespace SPIRV
-private:
- StorageTy Storage;
+// Bi-directional mappings between LLVM entities and (v-reg, machine function)
+// pairs support management of unique SPIR-V definitions per machine function
+// per an LLVM/GlobalISel entity (e.g., Type, Constant, Machine Instruction).
+class SPIRVIRMap {
+ DenseMap < std::pair<IRHandle, const MachineFunction *>, Register >> Vregs;
+ DenseMap<const MachineInstr *, IRHandle> Defs;
public:
- void add(KeyTy V, const MachineFunction *MF, Register R) {
- if (find(V, MF).isValid())
- return;
-
- auto &S = Storage[V];
- S[MF] = R;
- if (std::is_same<Function,
- typename std::remove_const<
- typename std::remove_pointer<KeyTy>::type>::type>() ||
- std::is_same<Argument,
- typename std::remove_const<
- typename std::remove_pointer<KeyTy>::type>::type>())
- S.setIsFunc(true);
- if (std::is_same<GlobalVariable,
- typename std::remove_const<
- typename std::remove_pointer<KeyTy>::type>::type>())
- S.setIsGV(true);
- if (std::is_same<Constant,
- typename std::remove_const<
- typename std::remove_pointer<KeyTy>::type>::type>())
- S.setIsConst(true);
- }
-
- Register find(KeyTy V, const MachineFunction *MF) const {
- auto iter = Storage.find(V);
- if (iter != Storage.end()) {
- auto Map = iter->second;
- auto iter2 = Map.find(MF);
- if (iter2 != Map.end())
- return iter2->second;
+ bool add(IRHandle Handle, const MachineInstr *MI) {
+ auto [It, Inserted] =
+ Vregs.try_emplace(std::make_pair(Handle, MI->getMF()));
+ if (Inserted) {
+ It->second = MI->getOperand(0).getReg();
+ auto [_, IsConsistent] = Defs.insert_or_assign(MI, Handle);
+ assert(IsConsistent);
}
- return Register();
- }
-
- const StorageTy &getAllUses() const { return Storage; }
-
-private:
- StorageTy &getAllUses() { return Storage; }
-
- // The friend class needs to have access to the internal storage
- // to be able to build dependency graph, can't declare only one
- // function a 'friend' due to the incomplete declaration at this point
- // and mutual dependency problems.
- friend class SPIRVGeneralDuplicatesTracker;
-};
-
-template <typename T>
-class SPIRVDuplicatesTracker : public SPIRVDuplicatesTrackerBase<const T *> {};
-
-template <>
-class SPIRVDuplicatesTracker<SPIRV::SpecialTypeDescriptor>
- : public SPIRVDuplicatesTrackerBase<SPIRV::SpecialTypeDescriptor> {};
-
-class SPIRVGeneralDuplicatesTracker {
- SPIRVDuplicatesTracker<Type> TT;
- SPIRVDuplicatesTracker<Constant> CT;
- SPIRVDuplicatesTracker<GlobalVariable> GT;
- SPIRVDuplicatesTracker<Function> FT;
- SPIRVDuplicatesTracker<Argument> AT;
- SPIRVDuplicatesTracker<MachineInstr> MT;
- SPIRVDuplicatesTracker<SPIRV::SpecialTypeDescriptor> ST;
-
-public:
- void add(const Type *Ty, const MachineFunction *MF, Register R) {
- TT.add(unifyPtrType(Ty), MF, R);
- }
-
- void add(const Type *PointeeTy, unsigned AddressSpace,
- const MachineFunction *MF, Register R) {
- ST.add(SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace), MF,
- R);
+ return Inserted1;
}
-
- void add(const Constant *C, const MachineFunction *MF, Register R) {
- CT.add(C, MF, R);
+ bool erase(const MachineInstr *MI) {
+ bool Res = false;
+ if (auto It = Defs.find(MI); It != Defs.end()) {
+ Res = Vregs.erase(std::make_pair(It->second, MI->getMF()));
+ Defs.erase(It);
+ }
+ return Res;
}
-
- void add(const GlobalVariable *GV, const MachineFunction *MF, Register R) {
- GT.add(GV, MF, R);
+ Register find(IRHandle Handle, const MachineFunction *MF) {
+ if (auto It = Vregs.find(std::make_pair(Handle, MF)); It != Vregs.end())
+ return It->second;
+ return Register();
}
- void add(const Function *F, const MachineFunction *MF, Register R) {
- FT.add(F, MF, R);
+ // helpers
+ bool add(const Type *Ty, const MachineInstr *MI) {
+ return add(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MI);
}
-
- void add(const Argument *Arg, const MachineFunction *MF, Register R) {
- AT.add(Arg, MF, R);
+ void add(const void *Key, const MachineInstr *MI) {
+ return add(SPIRV::make_descr_ptr(Key), MI);
}
-
- void add(const MachineInstr *MI, const MachineFunction *MF, Register R) {
- MT.add(MI, MF, R);
+ bool add(const Type *PointeeTy, unsigned AddressSpace,
+ const MachineInstr *MI) {
+ return add(SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace),
+ MI);
}
-
- void add(const SPIRV::SpecialTypeDescriptor &TD, const MachineFunction *MF,
- Register R) {
- ST.add(TD, MF, R);
- }
-
Register find(const Type *Ty, const MachineFunction *MF) {
- return TT.find(unifyPtrType(Ty), MF);
+ return find(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MF);
+ }
+ Register find(const void *Key, const MachineFunction *MF) {
+ return find(SPIRV::make_descr_ptr(Key), MF);
}
-
Register find(const Type *PointeeTy, unsigned AddressSpace,
const MachineFunction *MF) {
- return ST.find(
+ return find(
SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace), MF);
}
-
- Register find(const Constant *C, const MachineFunction *MF) {
- return CT.find(const_cast<Constant *>(C), MF);
- }
-
- Register find(const GlobalVariable *GV, const MachineFunction *MF) {
- return GT.find(const_cast<GlobalVariable *>(GV), MF);
- }
-
- Register find(const Function *F, const MachineFunction *MF) {
- return FT.find(const_cast<Function *>(F), MF);
- }
-
- Register find(const Argument *Arg, const MachineFunction *MF) {
- return AT.find(const_cast<Argument *>(Arg), MF);
- }
-
- Register find(const MachineInstr *MI, const MachineFunction *MF) {
- return MT.find(const_cast<MachineInstr *>(MI), MF);
- }
-
- Register find(const SPIRV::SpecialTypeDescriptor &TD,
- const MachineFunction *MF) {
- return ST.find(TD, MF);
- }
-
- const SPIRVDuplicatesTracker<Type> *getTypes() { return &TT; }
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_SPIRV_SPIRVDUPLICATESTRACKER_H
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index fb718d9ddd0b4..c897026dc2426 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -181,7 +181,7 @@ void SPIRVGlobalRegistry::invalidateMachineInstr(MachineInstr *MI) {
// - take into account duplicate tracker case which is a known issue,
// - review other data structure wrt. possible issues related to removal
// of a machine instruction during instruction selection.
- const MachineFunction *MF = MI->getParent()->getParent();
+ const MachineFunction *MF = MI->getMF();
auto It = LastInsertedTypeMap.find(MF);
if (It == LastInsertedTypeMap.end())
return;
@@ -245,98 +245,46 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeVector(uint32_t NumElems,
});
}
-std::tuple<Register, ConstantInt *, bool, unsigned>
-SPIRVGlobalRegistry::getOrCreateConstIntReg(uint64_t Val, SPIRVType *SpvType,
- MachineIRBuilder *MIRBuilder,
- MachineInstr *I,
- const SPIRVInstrInfo *TII) {
- assert(SpvType);
- const IntegerType *LLVMIntTy =
- cast<IntegerType>(getTypeForSPIRVType(SpvType));
- unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
- bool NewInstr = false;
- // Find a constant in DT or build a new one.
- ConstantInt *CI = ConstantInt::get(const_cast<IntegerType *>(LLVMIntTy), Val);
- Register Res = DT.find(CI, CurMF);
- if (!Res.isValid()) {
- Res =
- CurMF->getRegInfo().createGenericVirtualRegister(LLT::scalar(BitWidth));
- CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
- if (MIRBuilder)
- assignTypeToVReg(LLVMIntTy, Res, *MIRBuilder,
- SPIRV::AccessQualifier::ReadWrite, true);
- else
- assignIntTypeToVReg(BitWidth, Res, *I, *TII);
- DT.add(CI, CurMF, Res);
- NewInstr = true;
- }
- return std::make_tuple(Res, CI, NewInstr, BitWidth);
-}
-
-std::tuple<Register, ConstantFP *, bool, unsigned>
-SPIRVGlobalRegistry::getOrCreateConstFloatReg(APFloat Val, SPIRVType *SpvType,
- MachineIRBuilder *MIRBuilder,
- MachineInstr *I,
- const SPIRVInstrInfo *TII) {
- assert(SpvType);
- LLVMContext &Ctx = CurMF->getFunction().getContext();
- const Type *LLVMFloatTy = getTypeForSPIRVType(SpvType);
- unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
- bool NewInstr = false;
- // Find a constant in DT or build a new one.
- auto *const CI = ConstantFP::get(Ctx, Val);
- Register Res = DT.find(CI, CurMF);
- if (!Res.isValid()) {
- Res =
- CurMF->getRegInfo().createGenericVirtualRegister(LLT::scalar(BitWidth));
- CurMF->getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
- if (MIRBuilder)
- assignTypeToVReg(LLVMFloatTy, Res, *MIRBuilder,
- SPIRV::AccessQualifier::ReadWrite, true);
- else
- assignFloatTypeToVReg(BitWidth, Res, *I, *TII);
- DT.add(CI, CurMF, Res);
- NewInstr = true;
- }
- return std::make_tuple(Res, CI, NewInstr, BitWidth);
-}
-
Register SPIRVGlobalRegistry::getOrCreateConstFP(APFloat Val, MachineInstr &I,
SPIRVType *SpvType,
const SPIRVInstrInfo &TII,
bool ZeroAsNull) {
- assert(SpvType);
- ConstantFP *CI;
- Register Res;
- bool New;
- unsigned BitWidth;
- std::tie(Res, CI, New, BitWidth) =
- getOrCreateConstFloatReg(Val, SpvType, nullptr, &I, &TII);
- // If we have found Res register which is defined by the passed G_CONSTANT
- // machine instruction, a new constant instruction should be created.
- if (!New && (!I.getOperand(0).isReg() || Res != I.getOperand(0).getReg()))
+ unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
+ LLVMContext &Ctx = CurMF->getFunction().getContext();
+ auto *const CF = ConstantFP::get(Ctx, Val);
+ Register Res = find(CF, CurMF);
+ if (Res.isValid())
return Res;
+
+ LLT LLTy = LLT::scalar(BitWidth);
+ Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ CurMF->getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
+ assignFloatTypeToVReg(BitWidth, Res, I, TII);
+
MachineIRBuilder MIRBuilder(I);
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- MachineInstrBuilder MIB;
- // In OpenCL OpConstantNull - Scalar floating point: +0.0 (all bits 0)
- if (Val.isPosZero() && ZeroAsNull) {
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- } else {
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF)
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- addNumImm(
- APInt(BitWidth, CI->getValueAPF().bitcastToAPInt().getZExtValue()),
- MIB);
- }
- const auto &ST = CurMF->getSubtarget();
- constrainSelectedInstRegOperands(
- *MIB, *ST.getInstrInfo(), *ST.getRegisterInfo(), *ST.getRegBankInfo());
- return MIB;
- });
+ SPIRVType *NewType =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ MachineInstrBuilder MIB;
+ // In OpenCL OpConstantNull - Scalar floating point: +0.0 (all bits 0)
+ if (Val.isPosZero() && ZeroAsNull) {
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ } else {
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ addNumImm(APInt(BitWidth,
+ CI->getValueAPF().bitcastToAPInt().getZExtValue()),
+ MIB);
+ }
+ const auto &ST = CurMF->getSubtarget();
+ constrainSelectedInstRegOperands(*MIB, *ST.getInstrInfo(),
+ *ST.getRegisterInfo(),
+ *ST.getRegBankInfo());
+ return MIB;
+ });
+ add(CI, NewType);
return Res;
}
@@ -344,36 +292,37 @@ Register SPIRVGlobalRegistry::getOrCreateConstInt(uint64_t Val, MachineInstr &I,
SPIRVType *SpvType,
const SPIRVInstrInfo &TII,
bool ZeroAsNull) {
- assert(SpvType);
- ConstantInt *CI;
- Register Res;
- bool New;
- unsigned BitWidth;
- std::tie(Res, CI, New, BitWidth) =
- getOrCreateConstIntReg(Val, SpvType, nullptr, &I, &TII);
- // If we have found Res register which is defined by the passed G_CONSTANT
- // machine instruction, a new constant instruction should be created.
- if (!New && (!I.getOperand(0).isReg() || Res != I.getOperand(0).getReg()))
+ const IntegerType *Ty = cast<IntegerType>(getTypeForSPIRVType(SpvType));
+ unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
+ auto *const CI = ConstantInt::get(const_cast<IntegerType *>(Ty), Val);
+ Register Res = find(CI, CurMF);
+ if (Res.isValid())
return Res;
-
+ LLT LLTy = LLT::scalar(BitWidth);
+ Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
+ assignIntTypeToVReg(BitWidth, Res, I, TII);
MachineIRBuilder MIRBuilder(I);
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- MachineInstrBuilder MIB;
- if (Val || !ZeroAsNull) {
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- addNumImm(APInt(BitWidth, Val), MIB);
- } else {
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- }
- const auto &ST = CurMF->getSubtarget();
- constrainSelectedInstRegOperands(
- *MIB, *ST.getInstrInfo(), *ST.getRegisterInfo(), *ST.getRegBankInfo());
- return MIB;
- });
+ SPIRVType *NewType =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ MachineInstrBuilder MIB;
+ if (Val || !ZeroAsNull) {
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ addNumImm(APInt(BitWidth, Val), MIB);
+ } else {
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ }
+ const auto &ST = CurMF->getSubtarget();
+ constrainSelectedInstRegOperands(*MIB, *ST.getInstrInfo(),
+ *ST.getRegisterInfo(),
+ *ST.getRegBankInfo());
+ return MIB;
+ });
+ add(CI, NewType);
return Res;
}
@@ -383,27 +332,24 @@ Register SPIRVGlobalRegistry::buildConstantInt(uint64_t Val,
bool ZeroAsNull) {
assert(SpvType);
auto &MF = MIRBuilder.getMF();
- const IntegerType *LLVMIntTy =
- cast<IntegerType>(getTypeForSPIRVType(SpvType));
- // Find a constant in DT or build a new one.
- const auto ConstInt =
- ConstantInt::get(const_cast<IntegerType *>(LLVMIntTy), Val);
- Register Res = DT.find(ConstInt, &MF);
- if (!Res.isValid()) {
- unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
- LLT LLTy = LLT::scalar(BitWidth);
- Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
- MF.getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
- assignTypeToVReg(LLVMIntTy, Res, MIRBuilder,
- SPIRV::AccessQualifier::ReadWrite, EmitIR);
- DT.add(ConstInt, &MIRBuilder.getMF(), Res);
- if (EmitIR) {
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return MIRBuilder.buildConstant(Res, *ConstInt);
- });
- } else {
- Register SpvTypeReg = getSPIRVTypeID(SpvType);
+ const IntegerType *Ty = cast<IntegerType>(getTypeForSPIRVType(SpvType));
+ auto *const CI = ConstantInt::get(const_cast<IntegerType *>(Ty), Val);
+ Register Res = find(CI, &MF);
+ if (Res.isValid())
+ return Res;
+
+ unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
+ LLT LLTy = LLT::scalar(BitWidth);
+ Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
+ MF.getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
+ assignTypeToVReg(Ty, Res, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
+ EmitIR);
+
+ SPIRVType *NewType =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ if (EmitIR)
+ return MIRBuilder.buildConstant(Res, *CI);
+ Register SpvTypeReg = getSPIRVTypeID(SpvType);
MachineInstrBuilder MIB;
if (Val || !ZeroAsNull) {
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
@@ -421,8 +367,7 @@ Register SPIRVGlobalRegistry::buildConstantInt(uint64_t Val,
*Subtarget.getRegBankInfo());
return MIB;
});
- }
- }
+ add(ConstInt, NewType);
return Res;
}
@@ -430,31 +375,30 @@ Register SPIRVGlobalRegistry::buildConstantFP(APFloat Val,
MachineIRBuilder &MIRBuilder,
SPIRVType *SpvType) {
auto &MF = MIRBuilder.getMF();
- auto &Ctx = MF.getFunction().getContext();
- if (!SpvType) {
- const Type *LLVMFPTy = Type::getFloatTy(Ctx);
- SpvType = getOrCreateSPIRVType(LLVMFPTy, MIRBuilder,
- SPIRV::AccessQualifier::ReadWrite, true);
- }
- // Find a constant in DT or build a new one.
- const auto ConstFP = ConstantFP::get(Ctx, Val);
- Register Res = DT.find(ConstFP, &MF);
- if (!Res.isValid()) {
- Res = MF.getRegInfo().createGenericVirtualRegister(
- LLT::scalar(getScalarOrVectorBitWidth(SpvType)));
- MF.getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
- assignSPIRVTypeToVReg(SpvType, Res, MF);
- DT.add(ConstFP, &MF, Res);
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- MachineInstrBuilder MIB;
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF)
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- addNumImm(ConstFP->getValueAPF().bitcastToAPInt(), MIB);
- return MIB;
- });
- }
+ if (!SpvType)
+ SpvType = getOrCreateSPIRVType(
+ Type::getFloatTy(MF.getFunction().getContext()), MIRBuilder,
+ SPIRV::AccessQualifier::ReadWrite, true);
+ auto *const CF = ConstantFP::get(Ctx, Val);
+ Register Res = find(CF, &MF);
+ if (Res.isValid())
+ return Res;
+ LLT LLTy = LLT::scalar(getScalarOrVectorBitWidth(SpvType));
+ Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
+ MF.getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
+ assignSPIRVTypeToVReg(SpvType, Res, MF);
+
+ SPIRVType *NewType =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ MachineInstrBuilder MIB;
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ addNumImm(CF->getValueAPF().bitcastToAPInt(), MIB);
+ return MIB;
+ });
+ add(CF, NewType);
return Res;
}
@@ -1044,13 +988,8 @@ SPIRVType *SPIRVGlobalRegistry::createSPIRVType(
SPIRV::AccessQualifier::AccessQualifier AccQual, bool EmitIR) {
if (isSpecialOpaqueType(Ty))
return getOrCreateSpecialType(Ty, MIRBuilder, AccQual);
- auto &TypeToSPIRVTypeMap = DT.getTypes()->getAllUses();
- auto t = TypeToSPIRVTypeMap.find(Ty);
- if (t != TypeToSPIRVTypeMap.end()) {
- auto tt = t->second.find(&MIRBuilder.getMF());
- if (tt != t->second.end())
- return getSPIRVTypeForVReg(tt->second);
- }
+ if (Register TyReg = DT.find(Ty, &MIRBuilder.getMF()); TyReg.isValid())
+ return getSPIRVTypeForVReg(TyReg);
if (auto IType = dyn_cast<IntegerType>(Ty)) {
const unsigned Width = IType->getBitWidth();
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 467d9b73e2e39..8840401fe996d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -27,7 +27,7 @@ namespace llvm {
class SPIRVSubtarget;
using SPIRVType = const MachineInstr;
-class SPIRVGlobalRegistry {
+class SPIRVGlobalRegistry : public SPIRVIRMap {
// Registers holding values which have types associated with them.
// Initialized upon VReg definition in IRTranslator.
// Do not confuse this with DuplicatesTracker as DT maps Type* to <MF, Reg>
@@ -37,9 +37,6 @@ class SPIRVGlobalRegistry {
DenseMap<const MachineFunction *, DenseMap<Register, SPIRVType *>>
VRegToTypeMap;
- // Map LLVM Type* to <MF, Reg>
- SPIRVGeneralDuplicatesTracker DT;
-
DenseMap<SPIRVType *, const Type *> SPIRVToLLVMType;
// map a Function to its definition (as a machine instruction operand)
@@ -119,42 +116,6 @@ class SPIRVGlobalRegistry {
MachineFunction *CurMF;
- void add(const Constant *C, MachineFunction *MF, Register R) {
- DT.add(C, MF, R);
- }
-
- void add(const GlobalVariable *GV, MachineFunction *MF, Register R) {
- DT.add(GV, MF, R);
- }
-
- void add(const Function *F, MachineFunction *MF, Register R) {
- DT.add(F, MF, R);
- }
-
- void add(const Argument *Arg, MachineFunction *MF, Register R) {
- DT.add(Arg, MF, R);
- }
-
- void add(const MachineInstr *MI, MachineFunction *MF, Register R) {
- DT.add(MI, MF, R);
- }
-
- Register find(const MachineInstr *MI, MachineFunction *MF) {
- return DT.find(MI, MF);
- }
-
- Register find(const Constant *C, MachineFunction *MF) {
- return DT.find(C, MF);
- }
-
- Register find(const GlobalVariable *GV, MachineFunction *MF) {
- return DT.find(GV, MF);
- }
-
- Register find(const Function *F, MachineFunction *MF) {
- return DT.find(F, MF);
- }
-
void setBound(unsigned V) { Bound = V; }
unsigned getBound() { return Bound; }
>From 5da3d35fe0a1e8292f11f5746ad7c24697f0199e Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Tue, 11 Mar 2025 05:37:03 -0700
Subject: [PATCH 04/12] add a new duplicate tracker
---
.../lib/Target/SPIRV/SPIRVDuplicatesTracker.h | 14 +-
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 361 +++++++++---------
2 files changed, 192 insertions(+), 183 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
index 21e1069adb2d3..aa3171f3e7d10 100644
--- a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
+++ b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
@@ -119,15 +119,15 @@ inline IRHandle make_descr_ptr(const void *Ptr) {
// pairs support management of unique SPIR-V definitions per machine function
// per an LLVM/GlobalISel entity (e.g., Type, Constant, Machine Instruction).
class SPIRVIRMap {
- DenseMap < std::pair<IRHandle, const MachineFunction *>, Register >> Vregs;
+ DenseMap < std::pair<IRHandle, const MachineFunction *>,
+ const MachineInstr *MI >> Vregs;
DenseMap<const MachineInstr *, IRHandle> Defs;
public:
bool add(IRHandle Handle, const MachineInstr *MI) {
auto [It, Inserted] =
- Vregs.try_emplace(std::make_pair(Handle, MI->getMF()));
+ Vregs.try_emplace(std::make_pair(Handle, MI->getMF()), MI);
if (Inserted) {
- It->second = MI->getOperand(0).getReg();
auto [_, IsConsistent] = Defs.insert_or_assign(MI, Handle);
assert(IsConsistent);
}
@@ -141,10 +141,14 @@ class SPIRVIRMap {
}
return Res;
}
- Register find(IRHandle Handle, const MachineFunction *MF) {
+ const MachineInstr *findMI(IRHandle Handle, const MachineFunction *MF) {
if (auto It = Vregs.find(std::make_pair(Handle, MF)); It != Vregs.end())
return It->second;
- return Register();
+ return nullptr;
+ }
+ Register find(IRHandle Handle, const MachineFunction *MF) {
+ const MachineInstr *MI = findMI(Handle, MF);
+ return MI ? MI->getOperand(0).getReg() : Register();
}
// helpers
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index c897026dc2426..c0735f380f82b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -426,47 +426,42 @@ Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
Constant *Val, MachineInstr &I, SPIRVType *SpvType,
const SPIRVInstrInfo &TII, Constant *CA, unsigned BitWidth,
unsigned ElemCnt, bool ZeroAsNull) {
- // Find a constant vector or array in DT or build a new one.
- Register Res = DT.find(CA, CurMF);
- // If no values are attached, the composite is null constant.
+ if (Register R = find(CA, CurMF); R.isValid())
+ return R;
+
bool IsNull = Val->isNullValue() && ZeroAsNull;
- if (!Res.isValid()) {
- // SpvScalConst should be created before SpvVecConst to avoid undefined ID
- // error on validation.
- // TODO: can moved below once sorting of types/consts/defs is implemented.
- Register SpvScalConst;
- if (!IsNull)
- SpvScalConst =
- getOrCreateBaseRegister(Val, I, SpvType, TII, BitWidth, ZeroAsNull);
-
- LLT LLTy = LLT::scalar(64);
- Register SpvVecConst =
- CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
- CurMF->getRegInfo().setRegClass(SpvVecConst, getRegClass(SpvType));
- assignSPIRVTypeToVReg(SpvType, SpvVecConst, *CurMF);
- DT.add(CA, CurMF, SpvVecConst);
- MachineIRBuilder MIRBuilder(I);
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- MachineInstrBuilder MIB;
- if (!IsNull) {
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantComposite)
- .addDef(SpvVecConst)
- .addUse(getSPIRVTypeID(SpvType));
- for (unsigned i = 0; i < ElemCnt; ++i)
- MIB.addUse(SpvScalConst);
- } else {
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
- .addDef(SpvVecConst)
- .addUse(getSPIRVTypeID(SpvType));
- }
- const auto &Subtarget = CurMF->getSubtarget();
- constrainSelectedInstRegOperands(*MIB, *Subtarget.getInstrInfo(),
- *Subtarget.getRegisterInfo(),
- *Subtarget.getRegBankInfo());
- return MIB;
- });
- return SpvVecConst;
- }
+ Register ElemReg;
+ if (!IsNull)
+ ElemReg =
+ getOrCreateBaseRegister(Val, I, SpvType, TII, BitWidth, ZeroAsNull);
+
+ LLT LLTy = LLT::scalar(64);
+ Register Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ CurMF->getRegInfo().setRegClass(Res, getRegClass(SpvType));
+ assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
+
+ MachineIRBuilder MIRBuilder(I);
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ MachineInstrBuilder MIB;
+ if (!IsNull) {
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantComposite)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ for (unsigned i = 0; i < ElemCnt; ++i)
+ MIB.addUse(ElemReg);
+ } else {
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ }
+ const auto &Subtarget = CurMF->getSubtarget();
+ constrainSelectedInstRegOperands(*MIB, *Subtarget.getInstrInfo(),
+ *Subtarget.getRegisterInfo(),
+ *Subtarget.getRegBankInfo());
+ return MIB;
+ });
+ add(CA, NewMI);
return Res;
}
@@ -536,42 +531,38 @@ Register SPIRVGlobalRegistry::getOrCreateConstIntArray(
Register SPIRVGlobalRegistry::getOrCreateIntCompositeOrNull(
uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR,
Constant *CA, unsigned BitWidth, unsigned ElemCnt) {
- Register Res = DT.find(CA, CurMF);
- if (!Res.isValid()) {
- Register SpvScalConst;
- if (Val || EmitIR) {
- SPIRVType *SpvBaseType =
- getOrCreateSPIRVIntegerType(BitWidth, MIRBuilder);
- SpvScalConst = buildConstantInt(Val, MIRBuilder, SpvBaseType, EmitIR);
- }
- LLT LLTy = EmitIR ? LLT::fixed_vector(ElemCnt, BitWidth) : LLT::scalar(64);
- Register SpvVecConst =
- CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
- CurMF->getRegInfo().setRegClass(SpvVecConst, &SPIRV::iIDRegClass);
- assignSPIRVTypeToVReg(SpvType, SpvVecConst, *CurMF);
- DT.add(CA, CurMF, SpvVecConst);
- if (EmitIR) {
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return MIRBuilder.buildSplatBuildVector(SpvVecConst, SpvScalConst);
- });
- } else {
+ if (Register R = find(CA, CurMF); R.isValid())
+ return R;
+
+ Register ElemReg;
+ if (Val || EmitIR) {
+ SPIRVType *SpvBaseType = getOrCreateSPIRVIntegerType(BitWidth, MIRBuilder);
+ ElemReg = buildConstantInt(Val, MIRBuilder, SpvBaseType, EmitIR);
+ }
+ LLT LLTy = EmitIR ? LLT::fixed_vector(ElemCnt, BitWidth) : LLT::scalar(64);
+ Register Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
+ assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
+
+ const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ if (EmitIR)
+ return MIRBuilder.buildSplatBuildVector(Res, ElemReg);
+
if (Val) {
auto MIB = MIRBuilder.buildInstr(SPIRV::OpConstantComposite)
- .addDef(SpvVecConst)
+ .addDef(Res)
.addUse(getSPIRVTypeID(SpvType));
for (unsigned i = 0; i < ElemCnt; ++i)
- MIB.addUse(SpvScalConst);
+ MIB.addUse(ElemReg);
return MIB;
- } else {
- return MIRBuilder.buildInstr(SPIRV::OpConstantNull)
- .addDef(SpvVecConst)
- .addUse(getSPIRVTypeID(SpvType));
}
+
+ return MIRBuilder.buildInstr(SPIRV::OpConstantNull)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
});
- }
- return SpvVecConst;
- }
+ add(CA, NewMI);
return Res;
}
@@ -595,24 +586,26 @@ SPIRVGlobalRegistry::getOrCreateConsIntVector(uint64_t Val,
Register
SPIRVGlobalRegistry::getOrCreateConstNullPtr(MachineIRBuilder &MIRBuilder,
SPIRVType *SpvType) {
- const Type *LLVMTy = getTypeForSPIRVType(SpvType);
- unsigned AddressSpace = typeToAddressSpace(LLVMTy);
- // Find a constant in DT or build a new one.
- Constant *CP = ConstantPointerNull::get(
- PointerType::get(LLVMTy->getContext(), AddressSpace));
- Register Res = DT.find(CP, CurMF);
- if (!Res.isValid()) {
- LLT LLTy = LLT::pointer(AddressSpace, PointerSize);
- Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
- CurMF->getRegInfo().setRegClass(Res, &SPIRV::pIDRegClass);
- assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return MIRBuilder.buildInstr(SPIRV::OpConstantNull)
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- });
- DT.add(CP, CurMF, Res);
- }
+ const Type *Ty = getTypeForSPIRVType(SpvType);
+ unsigned AddressSpace = typeToAddressSpace(Ty);
+ const Constant *CP = ConstantPointerNull::get(
+ PointerType::get(Ty->getContext(), AddressSpace));
+ Register Res = find(CP, CurMF);
+ if (Res.isValid())
+ return Res;
+
+ LLT LLTy = LLT::pointer(AddressSpace, PointerSize);
+ Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ CurMF->getRegInfo().setRegClass(Res, &SPIRV::pIDRegClass);
+ assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
+
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpConstantNull)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ });
+ add(CP, NewMI);
return Res;
}
@@ -620,7 +613,10 @@ Register
SPIRVGlobalRegistry::buildConstantSampler(Register ResReg, unsigned AddrMode,
unsigned Param, unsigned FilerMode,
MachineIRBuilder &MIRBuilder) {
- auto Sampler =
+ Register Res = find(CP, CurMF);
+ if (Res.isValid())
+ return Res;
+auto Sampler =
ResReg.isValid()
? ResReg
: MIRBuilder.getMRI()->createVirtualRegister(&SPIRV::iIDRegClass);
@@ -1290,117 +1286,125 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeImage(
uint32_t Depth, uint32_t Arrayed, uint32_t Multisampled, uint32_t Sampled,
SPIRV::ImageFormat::ImageFormat ImageFormat,
SPIRV::AccessQualifier::AccessQualifier AccessQual) {
- auto TD = SPIRV::make_descr_image(SPIRVToLLVMType.lookup(SampledType), Dim,
- Depth, Arrayed, Multisampled, Sampled,
- ImageFormat, AccessQual);
- if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
- return Res;
- Register ResVReg = createTypeVReg(MIRBuilder);
- DT.add(TD, &MIRBuilder.getMF(), ResVReg);
- auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeImage)
- .addDef(ResVReg)
- .addUse(getSPIRVTypeID(SampledType))
- .addImm(Dim)
- .addImm(Depth) // Depth (whether or not it is a Depth image).
- .addImm(Arrayed) // Arrayed.
- .addImm(Multisampled) // Multisampled (0 = only single-sample).
- .addImm(Sampled) // Sampled (0 = usage known at runtime).
- .addImm(ImageFormat);
-
- if (AccessQual != SPIRV::AccessQualifier::None)
- MIB.addImm(AccessQual);
- return MIB;
+ auto Key = SPIRV::make_descr_image(SPIRVToLLVMType.lookup(SampledType), Dim,
+ Depth, Arrayed, Multisampled, Sampled,
+ ImageFormat, AccessQual);
+ if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ auto MIB =
+ MIRBuilder.buildInstr(SPIRV::OpTypeImage)
+ .addDef(createTypeVReg(MIRBuilder))
+ .addUse(getSPIRVTypeID(SampledType))
+ .addImm(Dim)
+ .addImm(Depth) // Depth (whether or not it is a Depth image).
+ .addImm(Arrayed) // Arrayed.
+ .addImm(Multisampled) // Multisampled (0 = only single-sample).
+ .addImm(Sampled) // Sampled (0 = usage known at runtime).
+ .addImm(ImageFormat);
+ if (AccessQual != SPIRV::AccessQualifier::None)
+ MIB.addImm(AccessQual);
+ return MIB;
+ });
+ add(Key, NewMI);
+ return NewMI;
}
SPIRVType *
SPIRVGlobalRegistry::getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder) {
- auto TD = SPIRV::make_descr_sampler();
- if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
- return Res;
- Register ResVReg = createTypeVReg(MIRBuilder);
- DT.add(TD, &MIRBuilder.getMF(), ResVReg);
- return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return MIRBuilder.buildInstr(SPIRV::OpTypeSampler).addDef(ResVReg);
- });
+ auto Key = SPIRV::make_descr_sampler();
+ const MachineFunction *MF = &MIRBuilder.getMF();
+ if (const MachineInstr *MI = findMI(Key, MF))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpTypeSampler)
+ .addDef(createTypeVReg(MIRBuilder));
+ });
+ add(Key, NewMI);
+ return NewMI;
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypePipe(
MachineIRBuilder &MIRBuilder,
SPIRV::AccessQualifier::AccessQualifier AccessQual) {
- auto TD = SPIRV::make_descr_pipe(AccessQual);
- if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
- return Res;
- Register ResVReg = createTypeVReg(MIRBuilder);
- DT.add(TD, &MIRBuilder.getMF(), ResVReg);
- return MIRBuilder.buildInstr(SPIRV::OpTypePipe)
- .addDef(ResVReg)
- .addImm(AccessQual);
+ auto Key = SPIRV::make_descr_pipe(AccessQual);
+ if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpTypePipe)
+ .addDef(createTypeVReg(MIRBuilder))
+ .addImm(AccessQual);
+ });
+ add(Key, NewMI);
+ return NewMI;
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeDeviceEvent(
MachineIRBuilder &MIRBuilder) {
- auto TD = SPIRV::make_descr_event();
- if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
- return Res;
- Register ResVReg = createTypeVReg(MIRBuilder);
- DT.add(TD, &MIRBuilder.getMF(), ResVReg);
- return MIRBuilder.buildInstr(SPIRV::OpTypeDeviceEvent).addDef(ResVReg);
+ auto Key = SPIRV::make_descr_event();
+ if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpTypeDeviceEvent)
+ .addDef(createTypeVReg(MIRBuilder));
+ });
+ add(Key, NewMI);
+ return NewMI;
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeSampledImage(
SPIRVType *ImageType, MachineIRBuilder &MIRBuilder) {
- auto TD = SPIRV::make_descr_sampled_image(
+ auto Key = SPIRV::make_descr_sampled_image(
SPIRVToLLVMType.lookup(MIRBuilder.getMF().getRegInfo().getVRegDef(
ImageType->getOperand(1).getReg())),
ImageType);
- if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
- return Res;
- Register ResVReg = createTypeVReg(MIRBuilder);
- DT.add(TD, &MIRBuilder.getMF(), ResVReg);
- return MIRBuilder.buildInstr(SPIRV::OpTypeSampledImage)
- .addDef(ResVReg)
- .addUse(getSPIRVTypeID(ImageType));
+ if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpTypeSampledImage)
+ .addDef(createTypeVReg(MIRBuilder))
+ .addUse(getSPIRVTypeID(ImageType));
+ });
+ add(Key, NewMI);
+ return NewMI;
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeCoopMatr(
MachineIRBuilder &MIRBuilder, const TargetExtType *ExtensionType,
const SPIRVType *ElemType, uint32_t Scope, uint32_t Rows, uint32_t Columns,
uint32_t Use, bool EmitIR) {
- Register ResVReg = DT.find(ExtensionType, &MIRBuilder.getMF());
- if (ResVReg.isValid())
- return MIRBuilder.getMF().getRegInfo().getUniqueVRegDef(ResVReg);
- ResVReg = createTypeVReg(MIRBuilder);
- SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType(32, MIRBuilder);
- SPIRVType *SpirvTy =
- MIRBuilder.buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
- .addDef(ResVReg)
- .addUse(getSPIRVTypeID(ElemType))
- .addUse(buildConstantInt(Scope, MIRBuilder, SpvTypeInt32, EmitIR))
- .addUse(buildConstantInt(Rows, MIRBuilder, SpvTypeInt32, EmitIR))
- .addUse(buildConstantInt(Columns, MIRBuilder, SpvTypeInt32, EmitIR))
- .addUse(buildConstantInt(Use, MIRBuilder, SpvTypeInt32, EmitIR));
- DT.add(ExtensionType, &MIRBuilder.getMF(), ResVReg);
- return SpirvTy;
+ if (const MachineInstr *MI = findMI(ExtensionType, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType(32, MIRBuilder);
+ return MIRBuilder.buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
+ .addDef(createTypeVReg(MIRBuilder))
+ .addUse(getSPIRVTypeID(ElemType))
+ .addUse(buildConstantInt(Scope, MIRBuilder, SpvTypeInt32, EmitIR))
+ .addUse(buildConstantInt(Rows, MIRBuilder, SpvTypeInt32, EmitIR))
+ .addUse(buildConstantInt(Columns, MIRBuilder, SpvTypeInt32, EmitIR))
+ .addUse(buildConstantInt(Use, MIRBuilder, SpvTypeInt32, EmitIR));
+ });
+ add(Key, NewMI);
+ return NewMI;
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeByOpcode(
const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode) {
- Register ResVReg = DT.find(Ty, &MIRBuilder.getMF());
- if (ResVReg.isValid())
- return MIRBuilder.getMF().getRegInfo().getUniqueVRegDef(ResVReg);
- ResVReg = createTypeVReg(MIRBuilder);
- SPIRVType *SpirvTy = MIRBuilder.buildInstr(Opcode).addDef(ResVReg);
- DT.add(Ty, &MIRBuilder.getMF(), ResVReg);
- return SpirvTy;
-}
-
-const MachineInstr *
-SPIRVGlobalRegistry::checkSpecialInstr(const SPIRV::SpecialTypeDescriptor &TD,
- MachineIRBuilder &MIRBuilder) {
- Register Reg = DT.find(TD, &MIRBuilder.getMF());
- if (Reg.isValid())
- return MIRBuilder.getMF().getRegInfo().getUniqueVRegDef(Reg);
- return nullptr;
+ if (const MachineInstr *MI = findMI(Ty, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(Opcode).addDef(createTypeVReg(MIRBuilder));
+ });
+ add(Key, NewMI);
+ return NewMI;
}
// Returns nullptr if unable to recognize SPIRV type name
@@ -1470,16 +1474,17 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVType(unsigned BitWidth,
MachineInstr &I,
const SPIRVInstrInfo &TII,
unsigned SPIRVOPcode,
- Type *LLVMTy) {
- Register Reg = DT.find(LLVMTy, CurMF);
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
- MachineBasicBlock &BB = *I.getParent();
- auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRVOPcode))
- .addDef(createTypeVReg(CurMF->getRegInfo()))
- .addImm(BitWidth)
- .addImm(0);
- DT.add(LLVMTy, CurMF, getSPIRVTypeID(MIB));
+ Type *Ty) {
+ if (const MachineInstr *MI = findMI(Ty, CurMF))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRVOPcode))
+ .addDef(createTypeVReg(CurMF->getRegInfo()))
+ .addImm(BitWidth)
+ .addImm(0);
+ });
+ add(LLVMTy, NewMI);
return finishCreatingSPIRVType(LLVMTy, MIB);
}
>From 1ab3c988c266a834074d227ebef17829cb47aff7 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Tue, 11 Mar 2025 05:39:47 -0700
Subject: [PATCH 05/12] a new duplicate tracker
---
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 10 ++--------
.../{SPIRVDuplicatesTracker.h => SPIRVIRMapping.h} | 8 ++++----
2 files changed, 6 insertions(+), 12 deletions(-)
rename llvm/lib/Target/SPIRV/{SPIRVDuplicatesTracker.h => SPIRVIRMapping.h} (96%)
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 8840401fe996d..6c2f08e315e3a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -17,7 +17,7 @@
#define LLVM_LIB_TARGET_SPIRV_SPIRVTYPEMANAGER_H
#include "MCTargetDesc/SPIRVBaseInfo.h"
-#include "SPIRVDuplicatesTracker.h"
+#include "SPIRVIRMapping.h"
#include "SPIRVInstrInfo.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/IR/Constant.h"
@@ -27,7 +27,7 @@ namespace llvm {
class SPIRVSubtarget;
using SPIRVType = const MachineInstr;
-class SPIRVGlobalRegistry : public SPIRVIRMap {
+class SPIRVGlobalRegistry : public SPIRVIRMapping {
// Registers holding values which have types associated with them.
// Initialized upon VReg definition in IRTranslator.
// Do not confuse this with DuplicatesTracker as DT maps Type* to <MF, Reg>
@@ -454,12 +454,6 @@ class SPIRVGlobalRegistry : public SPIRVIRMap {
getOrCreateSpecialType(const Type *Ty, MachineIRBuilder &MIRBuilder,
SPIRV::AccessQualifier::AccessQualifier AccQual);
- std::tuple<Register, ConstantInt *, bool, unsigned> getOrCreateConstIntReg(
- uint64_t Val, SPIRVType *SpvType, MachineIRBuilder *MIRBuilder,
- MachineInstr *I = nullptr, const SPIRVInstrInfo *TII = nullptr);
- std::tuple<Register, ConstantFP *, bool, unsigned> getOrCreateConstFloatReg(
- APFloat Val, SPIRVType *SpvType, MachineIRBuilder *MIRBuilder,
- MachineInstr *I = nullptr, const SPIRVInstrInfo *TII = nullptr);
SPIRVType *finishCreatingSPIRVType(const Type *LLVMTy, SPIRVType *SpirvType);
Register getOrCreateBaseRegister(Constant *Val, MachineInstr &I,
SPIRVType *SpvType,
diff --git a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
similarity index 96%
rename from llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
rename to llvm/lib/Target/SPIRV/SPIRVIRMapping.h
index aa3171f3e7d10..248384e50eac1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
+++ b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVDUPLICATESTRACKER_H
-#define LLVM_LIB_TARGET_SPIRV_SPIRVDUPLICATESTRACKER_H
+#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVIRMAPPING_H
+#define LLVM_LIB_TARGET_SPIRV_SPIRVIRMAPPING_H
#include "MCTargetDesc/SPIRVBaseInfo.h"
#include "MCTargetDesc/SPIRVMCTargetDesc.h"
@@ -118,7 +118,7 @@ inline IRHandle make_descr_ptr(const void *Ptr) {
// Bi-directional mappings between LLVM entities and (v-reg, machine function)
// pairs support management of unique SPIR-V definitions per machine function
// per an LLVM/GlobalISel entity (e.g., Type, Constant, Machine Instruction).
-class SPIRVIRMap {
+class SPIRVIRMapping {
DenseMap < std::pair<IRHandle, const MachineFunction *>,
const MachineInstr *MI >> Vregs;
DenseMap<const MachineInstr *, IRHandle> Defs;
@@ -176,4 +176,4 @@ class SPIRVIRMap {
}
};
} // namespace llvm
-#endif // LLVM_LIB_TARGET_SPIRV_SPIRVDUPLICATESTRACKER_H
+#endif // LLVM_LIB_TARGET_SPIRV_SPIRVIRMAPPING_H
>From 27285488b0d8e25cc3e29b623d77a29e1b172917 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Tue, 11 Mar 2025 07:03:18 -0700
Subject: [PATCH 06/12] a new duplicate tracker
---
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 299 +++++++++---------
llvm/lib/Target/SPIRV/SPIRVIRMapping.h | 4 +-
2 files changed, 148 insertions(+), 155 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index c0735f380f82b..69d707ca2ec15 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -613,23 +613,22 @@ Register
SPIRVGlobalRegistry::buildConstantSampler(Register ResReg, unsigned AddrMode,
unsigned Param, unsigned FilerMode,
MachineIRBuilder &MIRBuilder) {
- Register Res = find(CP, CurMF);
- if (Res.isValid())
- return Res;
-auto Sampler =
+ auto Sampler =
ResReg.isValid()
? ResReg
: MIRBuilder.getMRI()->createVirtualRegister(&SPIRV::iIDRegClass);
- auto Res = createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return MIRBuilder.buildInstr(SPIRV::OpConstantSampler)
- .addDef(Sampler)
- .addUse(getSPIRVTypeID(getOrCreateOpTypeSampler(MIRBuilder)))
- .addImm(AddrMode)
- .addImm(Param)
- .addImm(FilerMode);
- });
- assert(Res->getOperand(0).isReg());
- return Res->getOperand(0).getReg();
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpConstantSampler)
+ .addDef(Sampler)
+ .addUse(getSPIRVTypeID(getOrCreateOpTypeSampler(MIRBuilder)))
+ .addImm(AddrMode)
+ .addImm(Param)
+ .addImm(FilerMode);
+ });
+ // TODO: this is a constant and it needs a usual control flow of add()/find()
+ // as other constants
+ return NewMI->getOperand(0).getReg();
}
Register SPIRVGlobalRegistry::buildGlobalVariable(
@@ -639,9 +638,9 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
SPIRV::LinkageType::LinkageType LinkageType, MachineIRBuilder &MIRBuilder,
bool IsInstSelector) {
const GlobalVariable *GVar = nullptr;
- if (GV)
+ if (GV) {
GVar = cast<const GlobalVariable>(GV);
- else {
+ } else {
// If GV is not passed explicitly, use the name to find or construct
// the global variable.
Module *M = MIRBuilder.getMF().getFunction().getParent();
@@ -655,7 +654,9 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
}
GV = GVar;
}
- Register Reg = DT.find(GVar, &MIRBuilder.getMF());
+
+ const MachineFunction *MF = &MIRBuilder.getMF();
+ Register Reg = find(GVar, MF);
if (Reg.isValid()) {
if (Reg != ResVReg)
MIRBuilder.buildCopy(ResVReg, Reg);
@@ -666,11 +667,8 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
.addDef(ResVReg)
.addUse(getSPIRVTypeID(BaseType))
.addImm(static_cast<uint32_t>(Storage));
-
- if (Init != 0) {
+ if (Init != 0)
MIB.addUse(Init->getOperand(0).getReg());
- }
-
// ISel may introduce a new register on this step, so we need to add it to
// DT and correct its type avoiding fails on the next stage.
if (IsInstSelector) {
@@ -679,9 +677,10 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
*Subtarget.getRegisterInfo(),
*Subtarget.getRegBankInfo());
}
+ add(GVar, MIB);
+
Reg = MIB->getOperand(0).getReg();
- DT.add(GVar, &MIRBuilder.getMF(), Reg);
- addGlobalObject(GVar, &MIRBuilder.getMF(), Reg);
+ addGlobalObject(GVar, MF, Reg);
// Set to Reg the same type as ResVReg has.
auto MRI = MIRBuilder.getMRI();
@@ -866,23 +865,18 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeStruct(
if (Ty->isPacked())
buildOpDecorate(ResVReg, MIRBuilder, SPIRV::Decoration::CPacked, {});
- auto SPVType = createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeStruct).addDef(ResVReg);
+ return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ auto MIBStruct = MIRBuilder.buildInstr(SPIRV::OpTypeStruct).addDef(ResVReg);
for (size_t I = 0; I < SPIRVStructNumElements; ++I)
- MIB.addUse(FieldTypes[I]);
- return MIB;
- });
-
- for (size_t I = SPIRVStructNumElements; I < NumElements;
- I += MaxNumElements) {
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeStructContinuedINTEL);
+ MIBStruct.addUse(FieldTypes[I]);
+ for (size_t I = SPIRVStructNumElements; I < NumElements;
+ I += MaxNumElements) {
+ auto MIBCont = MIRBuilder.buildInstr(SPIRV::OpTypeStructContinuedINTEL);
for (size_t J = I; J < std::min(I + MaxNumElements, NumElements); ++J)
- MIB.addUse(FieldTypes[I]);
- return MIB;
- });
- }
- return SPVType;
+ MIBCont.addUse(FieldTypes[I]);
+ }
+ return MIBStruct;
+ });
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSpecialType(
@@ -918,33 +912,33 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeForwardPointer(
SPIRVType *SPIRVGlobalRegistry::getOpTypeFunction(
SPIRVType *RetType, const SmallVectorImpl<SPIRVType *> &ArgTypes,
MachineIRBuilder &MIRBuilder) {
- auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeFunction)
- .addDef(createTypeVReg(MIRBuilder))
- .addUse(getSPIRVTypeID(RetType));
- for (const SPIRVType *ArgType : ArgTypes)
- MIB.addUse(getSPIRVTypeID(ArgType));
- return MIB;
+ return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeFunction)
+ .addDef(createTypeVReg(MIRBuilder))
+ .addUse(getSPIRVTypeID(RetType));
+ for (const SPIRVType *ArgType : ArgTypes)
+ MIB.addUse(getSPIRVTypeID(ArgType));
+ return MIB;
+ });
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeFunctionWithArgs(
const Type *Ty, SPIRVType *RetType,
const SmallVectorImpl<SPIRVType *> &ArgTypes,
MachineIRBuilder &MIRBuilder) {
- Register Reg = DT.find(Ty, &MIRBuilder.getMF());
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
- SPIRVType *SpirvType = getOpTypeFunction(RetType, ArgTypes, MIRBuilder);
- DT.add(Ty, CurMF, getSPIRVTypeID(SpirvType));
- return finishCreatingSPIRVType(Ty, SpirvType);
+ if (const MachineInstr *MI = findMI(Ty, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI = getOpTypeFunction(RetType, ArgTypes, MIRBuilder);
+ add(Ty, NewMI);
+ return finishCreatingSPIRVType(Ty, NewMI);
}
SPIRVType *SPIRVGlobalRegistry::findSPIRVType(
const Type *Ty, MachineIRBuilder &MIRBuilder,
SPIRV::AccessQualifier::AccessQualifier AccQual, bool EmitIR) {
Ty = adjustIntTypeByWidth(Ty);
- Register Reg = DT.find(Ty, &MIRBuilder.getMF());
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
+ if (const MachineInstr *MI = findMI(Ty, &MIRBuilder.getMF()))
+ return MI;
if (auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end())
return It->second;
return restOfCreateSPIRVType(Ty, MIRBuilder, AccQual, EmitIR);
@@ -984,8 +978,9 @@ SPIRVType *SPIRVGlobalRegistry::createSPIRVType(
SPIRV::AccessQualifier::AccessQualifier AccQual, bool EmitIR) {
if (isSpecialOpaqueType(Ty))
return getOrCreateSpecialType(Ty, MIRBuilder, AccQual);
- if (Register TyReg = DT.find(Ty, &MIRBuilder.getMF()); TyReg.isValid())
- return getSPIRVTypeForVReg(TyReg);
+
+ if (const MachineInstr *MI = findMI(Ty, &MIRBuilder.getMF()))
+ return MI;
if (auto IType = dyn_cast<IntegerType>(Ty)) {
const unsigned Width = IType->getBitWidth();
@@ -1060,27 +1055,22 @@ SPIRVType *SPIRVGlobalRegistry::restOfCreateSPIRVType(
TypesInProcessing.erase(Ty);
VRegToTypeMap[&MIRBuilder.getMF()][getSPIRVTypeID(SpirvType)] = SpirvType;
SPIRVToLLVMType[SpirvType] = unifyPtrType(Ty);
- Register Reg = DT.find(Ty, &MIRBuilder.getMF());
- // Do not add OpTypeForwardPointer to DT, a corresponding normal pointer type
- // will be added later. For special types it is already added to DT.
- if (SpirvType->getOpcode() != SPIRV::OpTypeForwardPointer && !Reg.isValid() &&
- !isSpecialOpaqueType(Ty)) {
- if (auto *ExtTy = dyn_cast<TargetExtType>(Ty);
- ExtTy && isTypedPointerWrapper(ExtTy))
- DT.add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0),
- &MIRBuilder.getMF(), getSPIRVTypeID(SpirvType));
- else if (!isPointerTy(Ty))
- DT.add(Ty, &MIRBuilder.getMF(), getSPIRVTypeID(SpirvType));
- else if (isTypedPointerTy(Ty))
- DT.add(cast<TypedPointerType>(Ty)->getElementType(),
- getPointerAddressSpace(Ty), &MIRBuilder.getMF(),
- getSPIRVTypeID(SpirvType));
- else
- DT.add(Type::getInt8Ty(MIRBuilder.getMF().getFunction().getContext()),
- getPointerAddressSpace(Ty), &MIRBuilder.getMF(),
- getSPIRVTypeID(SpirvType));
- }
+ if (SpirvType->getOpcode() == SPIRV::OpTypeForwardPointer ||
+ findMI(Ty, &MIRBuilder.getMF()) || isSpecialOpaqueType(Ty))
+ return SpirvType;
+
+ if (auto *ExtTy = dyn_cast<TargetExtType>(Ty);
+ ExtTy && isTypedPointerWrapper(ExtTy))
+ add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), SpirvType);
+ else if (!isPointerTy(Ty))
+ add(Ty, SpirvType);
+ else if (isTypedPointerTy(Ty))
+ add(cast<TypedPointerType>(Ty)->getElementType(),
+ getPointerAddressSpace(Ty), SpirvType);
+ else
+ add(Type::getInt8Ty(MIRBuilder.getMF().getFunction().getContext()),
+ getPointerAddressSpace(Ty), SpirvType);
return SpirvType;
}
@@ -1107,32 +1097,29 @@ SPIRVType *SPIRVGlobalRegistry::getResultType(Register VReg,
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVType(
const Type *Ty, MachineIRBuilder &MIRBuilder,
SPIRV::AccessQualifier::AccessQualifier AccessQual, bool EmitIR) {
+ const MachineFunction *MF = &MIRBuilder.getMF();
Register Reg;
if (auto *ExtTy = dyn_cast<TargetExtType>(Ty);
- ExtTy && isTypedPointerWrapper(ExtTy)) {
- Reg = DT.find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0),
- &MIRBuilder.getMF());
- } else if (!isPointerTy(Ty)) {
- Ty = adjustIntTypeByWidth(Ty);
- Reg = DT.find(Ty, &MIRBuilder.getMF());
- } else if (isTypedPointerTy(Ty)) {
- Reg = DT.find(cast<TypedPointerType>(Ty)->getElementType(),
- getPointerAddressSpace(Ty), &MIRBuilder.getMF());
- } else {
- Reg =
- DT.find(Type::getInt8Ty(MIRBuilder.getMF().getFunction().getContext()),
- getPointerAddressSpace(Ty), &MIRBuilder.getMF());
- }
-
+ ExtTy && isTypedPointerWrapper(ExtTy))
+ Reg = find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), MF);
+ else if (!isPointerTy(Ty))
+ Reg = find(Ty = adjustIntTypeByWidth(Ty), MF);
+ else if (isTypedPointerTy(Ty))
+ Reg = find(cast<TypedPointerType>(Ty)->getElementType(),
+ getPointerAddressSpace(Ty), MF);
+ else
+ Reg = find(Type::getInt8Ty(MIRBuilder.getMF().getFunction().getContext()),
+ getPointerAddressSpace(Ty), MF);
if (Reg.isValid() && !isSpecialOpaqueType(Ty))
return getSPIRVTypeForVReg(Reg);
+
TypesInProcessing.clear();
SPIRVType *STy = restOfCreateSPIRVType(Ty, MIRBuilder, AccessQual, EmitIR);
// Create normal pointer types for the corresponding OpTypeForwardPointers.
for (auto &CU : ForwardPointerTypes) {
const Type *Ty2 = CU.first;
SPIRVType *STy2 = CU.second;
- if ((Reg = DT.find(Ty2, &MIRBuilder.getMF())).isValid())
+ if ((Reg = find(Ty2, MF)).isValid())
STy2 = getSPIRVTypeForVReg(Reg);
else
STy2 = restOfCreateSPIRVType(Ty2, MIRBuilder, AccessQual, EmitIR);
@@ -1530,15 +1517,17 @@ SPIRVGlobalRegistry::getOrCreateSPIRVBoolType(MachineIRBuilder &MIRBuilder,
SPIRVType *
SPIRVGlobalRegistry::getOrCreateSPIRVBoolType(MachineInstr &I,
const SPIRVInstrInfo &TII) {
- Type *LLVMTy = IntegerType::get(CurMF->getFunction().getContext(), 1);
- Register Reg = DT.find(LLVMTy, CurMF);
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
- MachineBasicBlock &BB = *I.getParent();
- auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpTypeBool))
- .addDef(createTypeVReg(CurMF->getRegInfo()));
- DT.add(LLVMTy, CurMF, getSPIRVTypeID(MIB));
- return finishCreatingSPIRVType(LLVMTy, MIB);
+ Type *Ty = IntegerType::get(CurMF->getFunction().getContext(), 1);
+ if (const MachineInstr *MI = findMI(Ty, CurMF))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return BuildMI(*I.getParent(), I, I.getDebugLoc(),
+ TII.get(SPIRV::OpTypeBool))
+ .addDef(createTypeVReg(CurMF->getRegInfo()));
+ });
+ add(Ty, NewMI);
+ return finishCreatingSPIRVType(Ty, NewMI);
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVVectorType(
@@ -1553,37 +1542,41 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVVectorType(
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVVectorType(
SPIRVType *BaseType, unsigned NumElements, MachineInstr &I,
const SPIRVInstrInfo &TII) {
- Type *LLVMTy = FixedVectorType::get(
+ Type *Ty = FixedVectorType::get(
const_cast<Type *>(getTypeForSPIRVType(BaseType)), NumElements);
- Register Reg = DT.find(LLVMTy, CurMF);
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
- MachineBasicBlock &BB = *I.getParent();
- auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpTypeVector))
- .addDef(createTypeVReg(CurMF->getRegInfo()))
- .addUse(getSPIRVTypeID(BaseType))
- .addImm(NumElements);
- DT.add(LLVMTy, CurMF, getSPIRVTypeID(MIB));
- return finishCreatingSPIRVType(LLVMTy, MIB);
+ if (const MachineInstr *MI = findMI(Ty, CurMF))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return BuildMI(*I.getParent(), I, I.getDebugLoc(),
+ TII.get(SPIRV::OpTypeVector))
+ .addDef(createTypeVReg(CurMF->getRegInfo()))
+ .addUse(getSPIRVTypeID(BaseType))
+ .addImm(NumElements);
+ });
+ add(Ty, NewMI);
+ return finishCreatingSPIRVType(Ty, NewMI);
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVArrayType(
SPIRVType *BaseType, unsigned NumElements, MachineInstr &I,
const SPIRVInstrInfo &TII) {
- Type *LLVMTy = ArrayType::get(
- const_cast<Type *>(getTypeForSPIRVType(BaseType)), NumElements);
- Register Reg = DT.find(LLVMTy, CurMF);
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
- MachineBasicBlock &BB = *I.getParent();
+ Type *Ty = ArrayType::get(const_cast<Type *>(getTypeForSPIRVType(BaseType)),
+ NumElements);
+ if (const MachineInstr *MI = findMI(Ty, CurMF))
+ return MI;
SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType(32, I, TII);
Register Len = getOrCreateConstInt(NumElements, I, SpvTypeInt32, TII);
- auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpTypeArray))
- .addDef(createTypeVReg(CurMF->getRegInfo()))
- .addUse(getSPIRVTypeID(BaseType))
- .addUse(Len);
- DT.add(LLVMTy, CurMF, getSPIRVTypeID(MIB));
- return finishCreatingSPIRVType(LLVMTy, MIB);
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return BuildMI(*I.getParent(), I, I.getDebugLoc(),
+ TII.get(SPIRV::OpTypeArray))
+ .addDef(createTypeVReg(CurMF->getRegInfo()))
+ .addUse(getSPIRVTypeID(BaseType))
+ .addUse(Len);
+ });
+ add(Ty, NewMI);
+ return finishCreatingSPIRVType(Ty, NewMI);
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
@@ -1591,24 +1584,21 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
SPIRV::StorageClass::StorageClass SC) {
const Type *PointerElementType = getTypeForSPIRVType(BaseType);
unsigned AddressSpace = storageClassToAddressSpace(SC);
- Type *LLVMTy = TypedPointerType::get(const_cast<Type *>(PointerElementType),
- AddressSpace);
- // check if this type is already available
- Register Reg = DT.find(PointerElementType, AddressSpace, CurMF);
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
- // create a new type
- return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- auto MIB = BuildMI(MIRBuilder.getMBB(), MIRBuilder.getInsertPt(),
+ if (const MachineInstr *MI = findMI(PointerElementType, AddressSpace, CurMF))
+ return MI;
+ Type *Ty = TypedPointerType::get(const_cast<Type *>(PointerElementType),
+ AddressSpace);
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return BuildMI(MIRBuilder.getMBB(), MIRBuilder.getInsertPt(),
MIRBuilder.getDebugLoc(),
MIRBuilder.getTII().get(SPIRV::OpTypePointer))
- .addDef(createTypeVReg(CurMF->getRegInfo()))
- .addImm(static_cast<uint32_t>(SC))
- .addUse(getSPIRVTypeID(BaseType));
- DT.add(PointerElementType, AddressSpace, CurMF, getSPIRVTypeID(MIB));
- finishCreatingSPIRVType(LLVMTy, MIB);
- return MIB;
- });
+ .addDef(createTypeVReg(CurMF->getRegInfo()))
+ .addImm(static_cast<uint32_t>(SC))
+ .addUse(getSPIRVTypeID(BaseType));
+ });
+ add(PointerElementType, AddressSpace, NewMI);
+ return finishCreatingSPIRVType(Ty, MIB);
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
@@ -1621,27 +1611,30 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
Register SPIRVGlobalRegistry::getOrCreateUndef(MachineInstr &I,
SPIRVType *SpvType,
const SPIRVInstrInfo &TII) {
- assert(SpvType);
- const Type *LLVMTy = getTypeForSPIRVType(SpvType);
- assert(LLVMTy);
- // Find a constant in DT or build a new one.
- UndefValue *UV = UndefValue::get(const_cast<Type *>(LLVMTy));
- Register Res = DT.find(UV, CurMF);
+ UndefValue *UV =
+ UndefValue::get(const_cast<Type *>(getTypeForSPIRVType(SpvType)));
+ Register Res = find(UV, CurMF);
if (Res.isValid())
return Res;
+
LLT LLTy = LLT::scalar(64);
Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
- DT.add(UV, CurMF, Res);
- MachineInstrBuilder MIB;
- MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpUndef))
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- const auto &ST = CurMF->getSubtarget();
- constrainSelectedInstRegOperands(*MIB, *ST.getInstrInfo(),
- *ST.getRegisterInfo(), *ST.getRegBankInfo());
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ auto MIB =
+ BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpUndef))
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ const auto &ST = CurMF->getSubtarget();
+ constrainSelectedInstRegOperands(*MIB, *ST.getInstrInfo(),
+ *ST.getRegisterInfo(),
+ *ST.getRegBankInfo());
+ return MIB;
+ });
+ add(UV, NewMI);
return Res;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
index 248384e50eac1..a70fde0a9ffc0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
+++ b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
@@ -110,8 +110,8 @@ inline IRHandle make_descr_pointee(const Type *ElementType,
SpecialTypeKind::STK_ElementPointer);
}
-inline IRHandle make_descr_ptr(const void *Ptr) {
- return std::make_tuple(Ptr, 0U, SpecialTypeKind::STK_Pointer);
+inline IRHandle make_descr_ptr(const void *Ptr, unsigned Arg = 0U) {
+ return std::make_tuple(Ptr, Arg, SpecialTypeKind::STK_Pointer);
}
} // namespace SPIRV
>From d577b10229d45f3f085df0ecb0d1e0ded85dd7b0 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Tue, 11 Mar 2025 07:54:33 -0700
Subject: [PATCH 07/12] a new duplicate tracker
---
llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp | 12 ++--
llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 8 +--
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 30 +++++----
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 5 --
llvm/lib/Target/SPIRV/SPIRVIRMapping.h | 29 ++++++---
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 65 ++++++++++---------
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 22 +++----
7 files changed, 93 insertions(+), 78 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
index 3039f975a4df2..d55631e0146cf 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
@@ -398,8 +398,6 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
auto MRI = MIRBuilder.getMRI();
Register FuncVReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
MRI->setRegClass(FuncVReg, &SPIRV::iIDRegClass);
- if (F.isDeclaration())
- GR->add(&F, &MIRBuilder.getMF(), FuncVReg);
FunctionType *FTy = getOriginalFunctionType(F);
Type *FRetTy = FTy->getReturnType();
if (isUntypedPointerTy(FRetTy)) {
@@ -425,6 +423,8 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
.addUse(GR->getSPIRVTypeID(FuncTy));
GR->recordFunctionDefinition(&F, &MB.getInstr()->getOperand(0));
GR->addGlobalObject(&F, &MIRBuilder.getMF(), FuncVReg);
+ if (F.isDeclaration())
+ GR->add(&F, MB);
// Add OpFunctionParameter instructions
int i = 0;
@@ -433,11 +433,11 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
Register ArgReg = VRegs[i][0];
MRI->setRegClass(ArgReg, GR->getRegClass(ArgTypeVRegs[i]));
MRI->setType(ArgReg, GR->getRegType(ArgTypeVRegs[i]));
- MIRBuilder.buildInstr(SPIRV::OpFunctionParameter)
- .addDef(ArgReg)
- .addUse(GR->getSPIRVTypeID(ArgTypeVRegs[i]));
+ auto MIB = MIRBuilder.buildInstr(SPIRV::OpFunctionParameter)
+ .addDef(ArgReg)
+ .addUse(GR->getSPIRVTypeID(ArgTypeVRegs[i]));
if (F.isDeclaration())
- GR->add(&Arg, &MIRBuilder.getMF(), ArgReg);
+ GR->add(&Arg, MIB);
GR->addGlobalObject(&Arg, &MIRBuilder.getMF(), ArgReg);
i++;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 356f4f6dab75c..cd01d158cc861 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -63,7 +63,7 @@ class SPIRVEmitIntrinsics
SPIRVTargetMachine *TM = nullptr;
SPIRVGlobalRegistry *GR = nullptr;
Function *CurrF = nullptr;
- bool TrackConstants = false;//true;
+ bool TrackConstants = true;
bool HaveFunPtrs = false;
DenseMap<Instruction *, Constant *> AggrConsts;
DenseMap<Instruction *, Type *> AggrConstTypes;
@@ -2025,7 +2025,7 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
auto *II = dyn_cast<IntrinsicInst>(I);
bool IsConstComposite =
II && II->getIntrinsicID() == Intrinsic::spv_const_composite;
- if (IsConstComposite) {
+ if (IsConstComposite && TrackConstants) {
setInsertPointAfterDef(B, I);
auto t = AggrConsts.find(I);
assert(t != AggrConsts.end());
@@ -2042,7 +2042,7 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
continue;
unsigned OpNo = Op.getOperandNo();
if (II && ((II->getIntrinsicID() == Intrinsic::spv_gep && OpNo == 0) ||
- (II->paramHasAttr(OpNo, Attribute::ImmArg))))
+ (II->paramHasAttr(OpNo, Attribute::ImmArg))))
continue;
if (!BPrepared) {
@@ -2421,7 +2421,7 @@ bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) {
deduceOperandElementType(&Phi, nullptr);
for (auto *I : Worklist) {
- TrackConstants = false;//true;
+ TrackConstants = true;
if (!I->getType()->isVoidTy() || isa<StoreInst>(I))
setInsertPointAfterDef(B, I);
// Visitors return either the original/newly created instruction for further
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 69d707ca2ec15..62e4d50b1926a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -178,7 +178,6 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeVoid(MachineIRBuilder &MIRBuilder) {
void SPIRVGlobalRegistry::invalidateMachineInstr(MachineInstr *MI) {
// TODO:
- // - take into account duplicate tracker case which is a known issue,
// - review other data structure wrt. possible issues related to removal
// of a machine instruction during instruction selection.
const MachineFunction *MF = MI->getMF();
@@ -187,6 +186,8 @@ void SPIRVGlobalRegistry::invalidateMachineInstr(MachineInstr *MI) {
return;
if (It->second == MI)
LastInsertedTypeMap.erase(MF);
+ // remove from the duplicate tracker to avoid incorrect reuse
+ erase(MI);
}
SPIRVType *SPIRVGlobalRegistry::createOpType(
@@ -275,7 +276,7 @@ Register SPIRVGlobalRegistry::getOrCreateConstFP(APFloat Val, MachineInstr &I,
.addDef(Res)
.addUse(getSPIRVTypeID(SpvType));
addNumImm(APInt(BitWidth,
- CI->getValueAPF().bitcastToAPInt().getZExtValue()),
+ CF->getValueAPF().bitcastToAPInt().getZExtValue()),
MIB);
}
const auto &ST = CurMF->getSubtarget();
@@ -284,7 +285,7 @@ Register SPIRVGlobalRegistry::getOrCreateConstFP(APFloat Val, MachineInstr &I,
*ST.getRegBankInfo());
return MIB;
});
- add(CI, NewType);
+ add(CF, NewType);
return Res;
}
@@ -367,7 +368,7 @@ Register SPIRVGlobalRegistry::buildConstantInt(uint64_t Val,
*Subtarget.getRegBankInfo());
return MIB;
});
- add(ConstInt, NewType);
+ add(CI, NewType);
return Res;
}
@@ -375,10 +376,10 @@ Register SPIRVGlobalRegistry::buildConstantFP(APFloat Val,
MachineIRBuilder &MIRBuilder,
SPIRVType *SpvType) {
auto &MF = MIRBuilder.getMF();
+ LLVMContext &Ctx = MF.getFunction().getContext();
if (!SpvType)
- SpvType = getOrCreateSPIRVType(
- Type::getFloatTy(MF.getFunction().getContext()), MIRBuilder,
- SPIRV::AccessQualifier::ReadWrite, true);
+ SpvType = getOrCreateSPIRVType(Type::getFloatTy(Ctx), MIRBuilder,
+ SPIRV::AccessQualifier::ReadWrite, true);
auto *const CF = ConstantFP::get(Ctx, Val);
Register Res = find(CF, &MF);
if (Res.isValid())
@@ -1378,7 +1379,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeCoopMatr(
.addUse(buildConstantInt(Columns, MIRBuilder, SpvTypeInt32, EmitIR))
.addUse(buildConstantInt(Use, MIRBuilder, SpvTypeInt32, EmitIR));
});
- add(Key, NewMI);
+ add(ExtensionType, NewMI);
return NewMI;
}
@@ -1390,7 +1391,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeByOpcode(
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
return MIRBuilder.buildInstr(Opcode).addDef(createTypeVReg(MIRBuilder));
});
- add(Key, NewMI);
+ add(Ty, NewMI);
return NewMI;
}
@@ -1464,6 +1465,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVType(unsigned BitWidth,
Type *Ty) {
if (const MachineInstr *MI = findMI(Ty, CurMF))
return MI;
+ MachineIRBuilder MIRBuilder(I);
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRVOPcode))
@@ -1471,8 +1473,8 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVType(unsigned BitWidth,
.addImm(BitWidth)
.addImm(0);
});
- add(LLVMTy, NewMI);
- return finishCreatingSPIRVType(LLVMTy, MIB);
+ add(Ty, NewMI);
+ return finishCreatingSPIRVType(Ty, NewMI);
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVIntegerType(
@@ -1520,6 +1522,7 @@ SPIRVGlobalRegistry::getOrCreateSPIRVBoolType(MachineInstr &I,
Type *Ty = IntegerType::get(CurMF->getFunction().getContext(), 1);
if (const MachineInstr *MI = findMI(Ty, CurMF))
return MI;
+ MachineIRBuilder MIRBuilder(I);
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
return BuildMI(*I.getParent(), I, I.getDebugLoc(),
@@ -1546,6 +1549,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVVectorType(
const_cast<Type *>(getTypeForSPIRVType(BaseType)), NumElements);
if (const MachineInstr *MI = findMI(Ty, CurMF))
return MI;
+ MachineIRBuilder MIRBuilder(I);
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
return BuildMI(*I.getParent(), I, I.getDebugLoc(),
@@ -1567,6 +1571,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVArrayType(
return MI;
SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType(32, I, TII);
Register Len = getOrCreateConstInt(NumElements, I, SpvTypeInt32, TII);
+ MachineIRBuilder MIRBuilder(I);
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
return BuildMI(*I.getParent(), I, I.getDebugLoc(),
@@ -1598,7 +1603,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
.addUse(getSPIRVTypeID(BaseType));
});
add(PointerElementType, AddressSpace, NewMI);
- return finishCreatingSPIRVType(Ty, MIB);
+ return finishCreatingSPIRVType(Ty, NewMI);
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
@@ -1622,6 +1627,7 @@ Register SPIRVGlobalRegistry::getOrCreateUndef(MachineInstr &I,
CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
+ MachineIRBuilder MIRBuilder(I);
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
auto MIB =
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 6c2f08e315e3a..3c6c11fae92b3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -55,11 +55,6 @@ class SPIRVGlobalRegistry : public SPIRVIRMapping {
// map an instruction to its value's attributes (type, name)
DenseMap<MachineInstr *, std::pair<Type *, std::string>> ValueAttrs;
- // Look for an equivalent of the newType in the map. Return the equivalent
- // if it's found, otherwise insert newType to the map and return the type.
- const MachineInstr *checkSpecialInstr(const SPIRV::SpecialTypeDescriptor &TD,
- MachineIRBuilder &MIRBuilder);
-
SmallPtrSet<const Type *, 4> TypesInProcessing;
DenseMap<const Type *, SPIRVType *> ForwardPointerTypes;
diff --git a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
index a70fde0a9ffc0..8f1a345565630 100644
--- a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
+++ b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
@@ -119,19 +119,20 @@ inline IRHandle make_descr_ptr(const void *Ptr, unsigned Arg = 0U) {
// pairs support management of unique SPIR-V definitions per machine function
// per an LLVM/GlobalISel entity (e.g., Type, Constant, Machine Instruction).
class SPIRVIRMapping {
- DenseMap < std::pair<IRHandle, const MachineFunction *>,
- const MachineInstr *MI >> Vregs;
- DenseMap<const MachineInstr *, IRHandle> Defs;
+ DenseMap<std::pair<SPIRV::IRHandle, const MachineFunction *>,
+ const MachineInstr *>
+ Vregs;
+ DenseMap<const MachineInstr *, SPIRV::IRHandle> Defs;
public:
- bool add(IRHandle Handle, const MachineInstr *MI) {
+ bool add(SPIRV::IRHandle Handle, const MachineInstr *MI) {
auto [It, Inserted] =
Vregs.try_emplace(std::make_pair(Handle, MI->getMF()), MI);
if (Inserted) {
auto [_, IsConsistent] = Defs.insert_or_assign(MI, Handle);
assert(IsConsistent);
}
- return Inserted1;
+ return Inserted;
}
bool erase(const MachineInstr *MI) {
bool Res = false;
@@ -141,12 +142,13 @@ class SPIRVIRMapping {
}
return Res;
}
- const MachineInstr *findMI(IRHandle Handle, const MachineFunction *MF) {
+ const MachineInstr *findMI(SPIRV::IRHandle Handle,
+ const MachineFunction *MF) {
if (auto It = Vregs.find(std::make_pair(Handle, MF)); It != Vregs.end())
return It->second;
return nullptr;
}
- Register find(IRHandle Handle, const MachineFunction *MF) {
+ Register find(SPIRV::IRHandle Handle, const MachineFunction *MF) {
const MachineInstr *MI = findMI(Handle, MF);
return MI ? MI->getOperand(0).getReg() : Register();
}
@@ -155,7 +157,7 @@ class SPIRVIRMapping {
bool add(const Type *Ty, const MachineInstr *MI) {
return add(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MI);
}
- void add(const void *Key, const MachineInstr *MI) {
+ bool add(const void *Key, const MachineInstr *MI) {
return add(SPIRV::make_descr_ptr(Key), MI);
}
bool add(const Type *PointeeTy, unsigned AddressSpace,
@@ -166,14 +168,25 @@ class SPIRVIRMapping {
Register find(const Type *Ty, const MachineFunction *MF) {
return find(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MF);
}
+ const MachineInstr *findMI(const Type *Ty, const MachineFunction *MF) {
+ return findMI(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MF);
+ }
Register find(const void *Key, const MachineFunction *MF) {
return find(SPIRV::make_descr_ptr(Key), MF);
}
+ const MachineInstr *findMI(const void *Key, const MachineFunction *MF) {
+ return findMI(SPIRV::make_descr_ptr(Key), MF);
+ }
Register find(const Type *PointeeTy, unsigned AddressSpace,
const MachineFunction *MF) {
return find(
SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace), MF);
}
+ const MachineInstr *findMI(const Type *PointeeTy, unsigned AddressSpace,
+ const MachineFunction *MF) {
+ return findMI(
+ SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace), MF);
+ }
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_SPIRV_SPIRVIRMAPPING_H
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index ce9ce3ef3135c..aa82f7f7d936a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -1213,16 +1213,17 @@ bool SPIRVInstructionSelector::selectMemOperation(Register ResVReg,
true, GlobalValue::InternalLinkage,
Constant::getNullValue(LLVMArrTy));
Register VarReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
- GR.add(GV, GR.CurMF, VarReg);
- GR.addGlobalObject(GV, GR.CurMF, VarReg);
-
- Result &=
+ auto MIBVar =
BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpVariable))
.addDef(VarReg)
.addUse(GR.getSPIRVTypeID(VarTy))
.addImm(SPIRV::StorageClass::UniformConstant)
- .addUse(Const)
- .constrainAllUses(TII, TRI, RBI);
+ .addUse(Const);
+ Result &= MIBVar.constrainAllUses(TII, TRI, RBI);
+
+ GR.add(GV, MIBVar);
+ GR.addGlobalObject(GV, GR.CurMF, VarReg);
+
buildOpDecorate(VarReg, I, TII, SPIRV::Decoration::Constant, {});
SPIRVType *SourceTy = GR.getOrCreateSPIRVPointerType(
ValTy, I, TII, SPIRV::StorageClass::UniformConstant);
@@ -1555,7 +1556,7 @@ SPIRVInstructionSelector::buildConstGenericPtr(MachineInstr &I, Register SrcPtr,
MachineInstrBuilder MIB = buildSpecConstantOp(
I, Tmp, SrcPtr, GR.getSPIRVTypeID(GenericPtrTy),
static_cast<uint32_t>(SPIRV::Opcode::PtrCastToGeneric));
- GR.add(MIB.getInstr(), MF, Tmp);
+ GR.add(MIB.getInstr(), MIB);
return MIB;
}
@@ -2505,20 +2506,18 @@ SPIRVInstructionSelector::buildI32Constant(uint32_t Val, MachineInstr &I,
bool Result = true;
if (!NewReg.isValid()) {
NewReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
- GR.add(ConstInt, GR.CurMF, NewReg);
- MachineInstr *MI;
MachineBasicBlock &BB = *I.getParent();
- if (Val == 0) {
- MI = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
- .addDef(NewReg)
- .addUse(GR.getSPIRVTypeID(SpvI32Ty));
- } else {
- MI = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantI))
- .addDef(NewReg)
- .addUse(GR.getSPIRVTypeID(SpvI32Ty))
- .addImm(APInt(32, Val).getZExtValue());
- }
+ MachineInstr *MI =
+ Val == 0
+ ? BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
+ .addDef(NewReg)
+ .addUse(GR.getSPIRVTypeID(SpvI32Ty))
+ : BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantI))
+ .addDef(NewReg)
+ .addUse(GR.getSPIRVTypeID(SpvI32Ty))
+ .addImm(APInt(32, Val).getZExtValue());
Result &= constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+ GR.add(ConstInt, MI);
}
return {NewReg, Result};
}
@@ -2895,18 +2894,18 @@ bool SPIRVInstructionSelector::wrapIntoSpecConstantOp(
}
// Create a new register for the wrapper
WrapReg = MRI->createVirtualRegister(GR.getRegClass(OpType));
- GR.add(OpDefine, MF, WrapReg);
CompositeArgs.push_back(WrapReg);
// Decorate the wrapper register and generate a new instruction
MRI->setType(WrapReg, LLT::pointer(0, 64));
GR.assignSPIRVTypeToVReg(OpType, WrapReg, *MF);
- MachineBasicBlock &BB = *I.getParent();
- Result = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpSpecConstantOp))
- .addDef(WrapReg)
- .addUse(GR.getSPIRVTypeID(OpType))
- .addImm(static_cast<uint32_t>(SPIRV::Opcode::Bitcast))
- .addUse(OpReg)
- .constrainAllUses(TII, TRI, RBI);
+ auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
+ TII.get(SPIRV::OpSpecConstantOp))
+ .addDef(WrapReg)
+ .addUse(GR.getSPIRVTypeID(OpType))
+ .addImm(static_cast<uint32_t>(SPIRV::Opcode::Bitcast))
+ .addUse(OpReg);
+ GR.add(OpDefine, MIB);
+ Result = MIB.constrainAllUses(TII, TRI, RBI);
if (!Result)
break;
}
@@ -3844,7 +3843,6 @@ bool SPIRVInstructionSelector::selectGlobalValue(
Register NewReg = GR.find(ConstVal, GR.CurMF);
if (!NewReg.isValid()) {
Register NewReg = ResVReg;
- GR.add(ConstVal, GR.CurMF, NewReg);
const Function *GVFun =
STI.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)
? dyn_cast<Function>(GV)
@@ -3872,15 +3870,18 @@ bool SPIRVInstructionSelector::selectGlobalValue(
.addDef(NewReg)
.addUse(ResTypeReg)
.addUse(FuncVReg);
+ GR.add(ConstVal, MIB2);
// mapping the function pointer to the used Function
GR.recordFunctionPointer(&MIB2.getInstr()->getOperand(2), GVFun);
return MIB1.constrainAllUses(TII, TRI, RBI) &&
MIB2.constrainAllUses(TII, TRI, RBI);
}
- return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
- .addDef(NewReg)
- .addUse(GR.getSPIRVTypeID(ResType))
- .constrainAllUses(TII, TRI, RBI);
+ MachineInstrBuilder MIB3 =
+ BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
+ .addDef(NewReg)
+ .addUse(GR.getSPIRVTypeID(ResType));
+ GR.add(ConstVal, MIB3);
+ return MIB3.constrainAllUses(TII, TRI, RBI);
}
assert(NewReg != ResVReg);
return BuildCOPY(ResVReg, NewReg, I);
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index edf215f0ce00f..da837c9ed85dd 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -48,8 +48,7 @@ void SPIRVPreLegalizer::getAnalysisUsage(AnalysisUsage &AU) const {
static void
addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
const SPIRVSubtarget &STI,
- DenseMap<MachineInstr *, Type *> &TargetExtConstTypes,
- SmallSet<Register, 4> &TrackedConstRegs) {
+ DenseMap<MachineInstr *, Type *> &TargetExtConstTypes) {
MachineRegisterInfo &MRI = MF.getRegInfo();
DenseMap<MachineInstr *, Register> RegsAlreadyAddedToDT;
SmallVector<MachineInstr *, 10> ToErase, ToEraseComposites;
@@ -66,7 +65,7 @@ addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
if (auto *GV = dyn_cast<GlobalValue>(Const)) {
Register Reg = GR->find(GV, &MF);
if (!Reg.isValid()) {
- GR->add(GV, &MF, SrcReg);
+ GR->add(GV, MRI.getVRegDef(SrcReg));
GR->addGlobalObject(GV, &MF, SrcReg);
} else
RegsAlreadyAddedToDT[&MI] = Reg;
@@ -77,22 +76,24 @@ addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
auto *BuildVec = MRI.getVRegDef(SrcReg);
assert(BuildVec &&
BuildVec->getOpcode() == TargetOpcode::G_BUILD_VECTOR);
+ GR->add(Const, BuildVec);
for (unsigned i = 0; i < ConstVec->getNumElements(); ++i) {
// Ensure that OpConstantComposite reuses a constant when it's
// already created and available in the same machine function.
Constant *ElemConst = ConstVec->getElementAsConstant(i);
Register ElemReg = GR->find(ElemConst, &MF);
if (!ElemReg.isValid())
- GR->add(ElemConst, &MF, BuildVec->getOperand(1 + i).getReg());
+ GR->add(ElemConst,
+ MRI.getVRegDef(BuildVec->getOperand(1 + i).getReg()));
else
BuildVec->getOperand(1 + i).setReg(ElemReg);
}
}
- GR->add(Const, &MF, SrcReg);
- TrackedConstRegs.insert(SrcReg);
if (Const->getType()->isTargetExtTy()) {
// remember association so that we can restore it when assign types
MachineInstr *SrcMI = MRI.getVRegDef(SrcReg);
+ if (SrcMI)
+ GR->add(Const, SrcMI);
if (SrcMI && (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT ||
SrcMI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF))
TargetExtConstTypes[SrcMI] = Const->getType();
@@ -595,7 +596,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
// pointers/PtrCast-null-in-OpSpecConstantOp.ll).
Register PrimaryReg = GR->find(OpCI, &MF);
if (!PrimaryReg.isValid()) {
- GR->add(OpCI, &MF, Reg);
+ GR->add(OpCI, &MI);
} else if (PrimaryReg != Reg &&
MRI.getType(Reg) == MRI.getType(PrimaryReg)) {
auto *RCReg = MRI.getRegClassOrNull(Reg);
@@ -730,7 +731,7 @@ insertInlineAsmProcess(MachineFunction &MF, SPIRVGlobalRegistry *GR,
auto AsmTargetMIB =
MIRBuilder.buildInstr(SPIRV::OpAsmTargetINTEL).addDef(AsmTargetReg);
addStringImm(ST.getTargetTripleAsStr(), AsmTargetMIB);
- GR->add(AsmTargetMIB.getInstr(), &MF, AsmTargetReg);
+ GR->add(AsmTargetMIB.getInstr(), AsmTargetMIB);
}
// create types
@@ -761,7 +762,7 @@ insertInlineAsmProcess(MachineFunction &MF, SPIRVGlobalRegistry *GR,
addStringImm(cast<MDString>(I1->getOperand(2).getMetadata()->getOperand(0))
->getString(),
AsmMIB);
- GR->add(AsmMIB.getInstr(), &MF, AsmReg);
+ GR->add(AsmMIB.getInstr(), AsmMIB);
// calls the inline assembly instruction
unsigned ExtraInfo = I2->getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
@@ -1034,8 +1035,7 @@ bool SPIRVPreLegalizer::runOnMachineFunction(MachineFunction &MF) {
// a registry of target extension constants
DenseMap<MachineInstr *, Type *> TargetExtConstTypes;
// to keep record of tracked constants
- SmallSet<Register, 4> TrackedConstRegs;
- addConstantsToTrack(MF, GR, ST, TargetExtConstTypes, TrackedConstRegs);
+ addConstantsToTrack(MF, GR, ST, TargetExtConstTypes);
foldConstantsIntoIntrinsics(MF, MIB);
insertBitcasts(MF, GR, MIB);
generateAssignInstrs(MF, GR, MIB, TargetExtConstTypes);
>From 429551babc8637c4bcb58d07fae45ca3b4c6f568 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Fri, 14 Mar 2025 08:39:19 -0700
Subject: [PATCH 08/12] rework assign_type, type/const instruction selection
---
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 2 +-
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 113 ++++---
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 6 +
llvm/lib/Target/SPIRV/SPIRVIRMapping.h | 155 ++++++---
llvm/lib/Target/SPIRV/SPIRVInstrInfo.td | 6 +-
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 297 +++++++++---------
llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 39 +--
llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.h | 2 -
llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp | 10 +-
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 126 +++++---
.../SPIRV/SPIRVPreLegalizerCombiner.cpp | 7 +-
llvm/lib/Target/SPIRV/SPIRVUtils.cpp | 96 +++++-
llvm/lib/Target/SPIRV/SPIRVUtils.h | 12 +
llvm/test/CodeGen/SPIRV/atomicrmw.ll | 4 +-
.../SPIRV/debug-info/debug-type-pointer.ll | 44 +--
llvm/test/CodeGen/SPIRV/freeze.ll | 11 +-
.../SPIRV/hlsl-intrinsics/dot4add_i8packed.ll | 2 +-
.../SPIRV/hlsl-intrinsics/dot4add_u8packed.ll | 2 +-
.../hlsl-resources/StorageImageDynIdx.ll | 8 +-
.../StorageImageNonUniformIdx.ll | 10 +-
.../llvm-intrinsics/smul.with.overflow.ll | 6 +-
.../llvm-intrinsics/uadd.with.overflow.ll | 6 +-
.../llvm-intrinsics/umul.with.overflow.ll | 6 +-
.../llvm-intrinsics/usub.with.overflow.ll | 6 +-
24 files changed, 577 insertions(+), 399 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index e6c0a526a9cec..4f5984d8823ab 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -535,7 +535,7 @@ static Register buildBuiltinVariableLoad(
/// assign SPIRVType to both registers. If SpirvTy is provided, use it as
/// SPIRVType in ASSIGN_TYPE, otherwise create it from \p Ty. Defined in
/// SPIRVPreLegalizer.cpp.
-extern Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
+extern void insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
SPIRVGlobalRegistry *GR,
MachineIRBuilder &MIB,
MachineRegisterInfo &MRI);
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 62e4d50b1926a..07138c625a1af 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -250,24 +250,32 @@ Register SPIRVGlobalRegistry::getOrCreateConstFP(APFloat Val, MachineInstr &I,
SPIRVType *SpvType,
const SPIRVInstrInfo &TII,
bool ZeroAsNull) {
- unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
LLVMContext &Ctx = CurMF->getFunction().getContext();
auto *const CF = ConstantFP::get(Ctx, Val);
- Register Res = find(CF, CurMF);
- if (Res.isValid())
- return Res;
+ const MachineInstr *MI = findMI(CF, CurMF);
+ if (MI && (MI->getOpcode() == SPIRV::OpConstantNull ||
+ MI->getOpcode() == SPIRV::OpConstantF))
+ return MI->getOperand(0).getReg();
+ return createConstFP(CF, I, SpvType, TII, ZeroAsNull);
+}
+Register SPIRVGlobalRegistry::createConstFP(const ConstantFP *CF,
+ MachineInstr &I, SPIRVType *SpvType,
+ const SPIRVInstrInfo &TII,
+ bool ZeroAsNull) {
+ unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
LLT LLTy = LLT::scalar(BitWidth);
- Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ Register Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
CurMF->getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
assignFloatTypeToVReg(BitWidth, Res, I, TII);
- MachineIRBuilder MIRBuilder(I);
+ MachineInstr *DepMI = const_cast<MachineInstr *>(SpvType);
+ MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
SPIRVType *NewType =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
MachineInstrBuilder MIB;
// In OpenCL OpConstantNull - Scalar floating point: +0.0 (all bits 0)
- if (Val.isPosZero() && ZeroAsNull) {
+ if (CF->getValue().isPosZero() && ZeroAsNull) {
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
.addDef(Res)
.addUse(getSPIRVTypeID(SpvType));
@@ -294,24 +302,35 @@ Register SPIRVGlobalRegistry::getOrCreateConstInt(uint64_t Val, MachineInstr &I,
const SPIRVInstrInfo &TII,
bool ZeroAsNull) {
const IntegerType *Ty = cast<IntegerType>(getTypeForSPIRVType(SpvType));
- unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
auto *const CI = ConstantInt::get(const_cast<IntegerType *>(Ty), Val);
- Register Res = find(CI, CurMF);
- if (Res.isValid())
- return Res;
+ const MachineInstr *MI = findMI(CI, CurMF);
+ if (MI && (MI->getOpcode() == SPIRV::OpConstantNull ||
+ MI->getOpcode() == SPIRV::OpConstantI))
+ return MI->getOperand(0).getReg();
+ return createConstInt(CI, I, SpvType, TII, ZeroAsNull);
+}
+
+Register SPIRVGlobalRegistry::createConstInt(const ConstantInt *CI,
+ MachineInstr &I,
+ SPIRVType *SpvType,
+ const SPIRVInstrInfo &TII,
+ bool ZeroAsNull) {
+ unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
LLT LLTy = LLT::scalar(BitWidth);
- Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ Register Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
assignIntTypeToVReg(BitWidth, Res, I, TII);
- MachineIRBuilder MIRBuilder(I);
+
+ MachineInstr *DepMI = const_cast<MachineInstr *>(SpvType);
+ MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
SPIRVType *NewType =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
MachineInstrBuilder MIB;
- if (Val || !ZeroAsNull) {
+ if (!CI->isZero() || !ZeroAsNull) {
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
.addDef(Res)
.addUse(getSPIRVTypeID(SpvType));
- addNumImm(APInt(BitWidth, Val), MIB);
+ addNumImm(APInt(BitWidth, CI->getZExtValue()), MIB);
} else {
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
.addDef(Res)
@@ -441,7 +460,8 @@ Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
CurMF->getRegInfo().setRegClass(Res, getRegClass(SpvType));
assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
- MachineIRBuilder MIRBuilder(I);
+ MachineInstr *DepMI = const_cast<MachineInstr *>(SpvType);
+ MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
MachineInstrBuilder MIB;
@@ -751,11 +771,7 @@ static std::string buildSpirvTypeName(const SPIRVType *Type,
MachineRegisterInfo *MRI = MIRBuilder.getMRI();
Register ElementTypeReg = Type->getOperand(1).getReg();
auto *ElementType = MRI->getUniqueVRegDef(ElementTypeReg);
- const SPIRVType *TypeInst = MRI->getVRegDef(Type->getOperand(2).getReg());
- assert(TypeInst->getOpcode() != SPIRV::OpConstantI);
- MachineInstr *ImmInst = MRI->getVRegDef(TypeInst->getOperand(1).getReg());
- assert(ImmInst->getOpcode() == TargetOpcode::G_CONSTANT);
- uint32_t ArraySize = ImmInst->getOperand(1).getCImm()->getZExtValue();
+ uint32_t ArraySize = getArrayComponentCount(MRI, Type);
return (buildSpirvTypeName(ElementType, MIRBuilder) + Twine("[") +
Twine(ArraySize) + Twine("]"))
.str();
@@ -1274,9 +1290,9 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeImage(
uint32_t Depth, uint32_t Arrayed, uint32_t Multisampled, uint32_t Sampled,
SPIRV::ImageFormat::ImageFormat ImageFormat,
SPIRV::AccessQualifier::AccessQualifier AccessQual) {
- auto Key = SPIRV::make_descr_image(SPIRVToLLVMType.lookup(SampledType), Dim,
- Depth, Arrayed, Multisampled, Sampled,
- ImageFormat, AccessQual);
+ auto Key = SPIRV::irhandle_image(SPIRVToLLVMType.lookup(SampledType), Dim,
+ Depth, Arrayed, Multisampled, Sampled,
+ ImageFormat, AccessQual);
if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
return MI;
const MachineInstr *NewMI =
@@ -1301,7 +1317,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeImage(
SPIRVType *
SPIRVGlobalRegistry::getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder) {
- auto Key = SPIRV::make_descr_sampler();
+ auto Key = SPIRV::irhandle_sampler();
const MachineFunction *MF = &MIRBuilder.getMF();
if (const MachineInstr *MI = findMI(Key, MF))
return MI;
@@ -1317,7 +1333,7 @@ SPIRVGlobalRegistry::getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder) {
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypePipe(
MachineIRBuilder &MIRBuilder,
SPIRV::AccessQualifier::AccessQualifier AccessQual) {
- auto Key = SPIRV::make_descr_pipe(AccessQual);
+ auto Key = SPIRV::irhandle_pipe(AccessQual);
if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
return MI;
const MachineInstr *NewMI =
@@ -1332,7 +1348,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypePipe(
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeDeviceEvent(
MachineIRBuilder &MIRBuilder) {
- auto Key = SPIRV::make_descr_event();
+ auto Key = SPIRV::irhandle_event();
if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
return MI;
const MachineInstr *NewMI =
@@ -1346,7 +1362,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeDeviceEvent(
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeSampledImage(
SPIRVType *ImageType, MachineIRBuilder &MIRBuilder) {
- auto Key = SPIRV::make_descr_sampled_image(
+ auto Key = SPIRV::irhandle_sampled_image(
SPIRVToLLVMType.lookup(MIRBuilder.getMF().getRegInfo().getVRegDef(
ImageType->getOperand(1).getReg())),
ImageType);
@@ -1465,10 +1481,12 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVType(unsigned BitWidth,
Type *Ty) {
if (const MachineInstr *MI = findMI(Ty, CurMF))
return MI;
- MachineIRBuilder MIRBuilder(I);
+ MachineBasicBlock &DepMBB = I.getMF()->front();
+ MachineIRBuilder MIRBuilder(DepMBB, DepMBB.getFirstNonPHI());
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRVOPcode))
+ return BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
+ MIRBuilder.getDL(), TII.get(SPIRVOPcode))
.addDef(createTypeVReg(CurMF->getRegInfo()))
.addImm(BitWidth)
.addImm(0);
@@ -1522,11 +1540,12 @@ SPIRVGlobalRegistry::getOrCreateSPIRVBoolType(MachineInstr &I,
Type *Ty = IntegerType::get(CurMF->getFunction().getContext(), 1);
if (const MachineInstr *MI = findMI(Ty, CurMF))
return MI;
- MachineIRBuilder MIRBuilder(I);
+ MachineBasicBlock &DepMBB = I.getMF()->front();
+ MachineIRBuilder MIRBuilder(DepMBB, DepMBB.getFirstNonPHI());
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(SPIRV::OpTypeBool))
+ return BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
+ MIRBuilder.getDL(), TII.get(SPIRV::OpTypeBool))
.addDef(createTypeVReg(CurMF->getRegInfo()));
});
add(Ty, NewMI);
@@ -1549,11 +1568,12 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVVectorType(
const_cast<Type *>(getTypeForSPIRVType(BaseType)), NumElements);
if (const MachineInstr *MI = findMI(Ty, CurMF))
return MI;
- MachineIRBuilder MIRBuilder(I);
+ MachineInstr *DepMI = const_cast<MachineInstr *>(BaseType);
+ MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(SPIRV::OpTypeVector))
+ return BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
+ MIRBuilder.getDL(), TII.get(SPIRV::OpTypeVector))
.addDef(createTypeVReg(CurMF->getRegInfo()))
.addUse(getSPIRVTypeID(BaseType))
.addImm(NumElements);
@@ -1571,11 +1591,12 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVArrayType(
return MI;
SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType(32, I, TII);
Register Len = getOrCreateConstInt(NumElements, I, SpvTypeInt32, TII);
- MachineIRBuilder MIRBuilder(I);
+ MachineBasicBlock &DepMBB = I.getMF()->front();
+ MachineIRBuilder MIRBuilder(DepMBB, getInsertPtValidEnd(&DepMBB));
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(SPIRV::OpTypeArray))
+ return BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
+ MIRBuilder.getDL(), TII.get(SPIRV::OpTypeArray))
.addDef(createTypeVReg(CurMF->getRegInfo()))
.addUse(getSPIRVTypeID(BaseType))
.addUse(Len);
@@ -1609,7 +1630,8 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
SPIRVType *BaseType, MachineInstr &I, const SPIRVInstrInfo &,
SPIRV::StorageClass::StorageClass SC) {
- MachineIRBuilder MIRBuilder(I);
+ MachineInstr *DepMI = const_cast<MachineInstr *>(BaseType);
+ MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
return getOrCreateSPIRVPointerType(BaseType, MIRBuilder, SC);
}
@@ -1627,13 +1649,14 @@ Register SPIRVGlobalRegistry::getOrCreateUndef(MachineInstr &I,
CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
- MachineIRBuilder MIRBuilder(I);
+ MachineInstr *DepMI = const_cast<MachineInstr *>(SpvType);
+ MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- auto MIB =
- BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpUndef))
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
+ auto MIB = BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
+ MIRBuilder.getDL(), TII.get(SPIRV::OpUndef))
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
const auto &ST = CurMF->getSubtarget();
constrainSelectedInstRegOperands(*MIB, *ST.getInstrInfo(),
*ST.getRegisterInfo(),
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 3c6c11fae92b3..385e424092d4a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -473,9 +473,15 @@ class SPIRVGlobalRegistry : public SPIRVIRMapping {
Register getOrCreateConstInt(uint64_t Val, MachineInstr &I,
SPIRVType *SpvType, const SPIRVInstrInfo &TII,
bool ZeroAsNull = true);
+ Register createConstInt(const ConstantInt *CI, MachineInstr &I,
+ SPIRVType *SpvType, const SPIRVInstrInfo &TII,
+ bool ZeroAsNull);
Register getOrCreateConstFP(APFloat Val, MachineInstr &I, SPIRVType *SpvType,
const SPIRVInstrInfo &TII,
bool ZeroAsNull = true);
+ Register createConstFP(const ConstantFP *CF, MachineInstr &I,
+ SPIRVType *SpvType, const SPIRVInstrInfo &TII,
+ bool ZeroAsNull);
Register buildConstantFP(APFloat Val, MachineIRBuilder &MIRBuilder,
SPIRVType *SpvType = nullptr);
diff --git a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
index 8f1a345565630..bec2a989483e8 100644
--- a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
+++ b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
@@ -18,7 +18,7 @@
#include "MCTargetDesc/SPIRVMCTargetDesc.h"
#include "SPIRVUtils.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/Hashing.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@@ -27,7 +27,39 @@
namespace llvm {
namespace SPIRV {
+inline size_t to_hash(const MachineInstr *MI,
+ std::unordered_set<const MachineInstr *> &Visited) {
+ if (!MI || !Visited.insert(MI).second)
+ return 0;
+ const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
+ SmallVector<size_t, 16> Codes{MI->getOpcode()};
+ size_t H;
+ for (unsigned I = MI->getNumDefs(); I < MI->getNumOperands(); ++I) {
+ const MachineOperand &MO = MI->getOperand(I);
+ H = MO.isReg() ? to_hash(getDef(MO, &MRI), Visited)
+ : size_t(llvm::hash_value(MO));
+ Codes.push_back(H);
+ }
+ return llvm::hash_combine(Codes.begin(), Codes.end());
+}
+
+inline size_t to_hash(const MachineInstr *MI) {
+ std::unordered_set<const MachineInstr *> Visited;
+ return to_hash(MI, Visited);
+}
+
+using MIHandle = std::pair<const MachineInstr *, size_t>;
+
+inline MIHandle getMIKey(const MachineInstr *MI) {
+ return std::make_pair(MI, SPIRV::to_hash(MI));
+}
+
using IRHandle = std::tuple<const void *, unsigned, unsigned>;
+using IRHandleMF = std::pair<IRHandle, const MachineFunction *>;
+
+inline IRHandleMF getIRHandleMF(IRHandle Handle, const MachineFunction *MF) {
+ return std::make_pair(Handle, MF);
+}
enum SpecialTypeKind {
STK_Empty = 0,
@@ -37,7 +69,9 @@ enum SpecialTypeKind {
STK_Pipe,
STK_DeviceEvent,
STK_ElementPointer,
- STK_Pointer,
+ STK_Type,
+ STK_Value,
+ STK_MachineInstr,
STK_Last = -1
};
@@ -66,18 +100,18 @@ union ImageAttrs {
}
};
-inline IRHandle make_descr_image(const Type *SampledTy, unsigned Dim,
- unsigned Depth, unsigned Arrayed, unsigned MS,
- unsigned Sampled, unsigned ImageFormat,
- unsigned AQ = 0) {
+inline IRHandle irhandle_image(const Type *SampledTy, unsigned Dim,
+ unsigned Depth, unsigned Arrayed, unsigned MS,
+ unsigned Sampled, unsigned ImageFormat,
+ unsigned AQ = 0) {
return std::make_tuple(
SampledTy,
ImageAttrs(Dim, Depth, Arrayed, MS, Sampled, ImageFormat, AQ).Val,
SpecialTypeKind::STK_Image);
}
-inline IRHandle make_descr_sampled_image(const Type *SampledTy,
- const MachineInstr *ImageTy) {
+inline IRHandle irhandle_sampled_image(const Type *SampledTy,
+ const MachineInstr *ImageTy) {
assert(ImageTy->getOpcode() == SPIRV::OpTypeImage);
unsigned AC = AccessQualifier::AccessQualifier::None;
if (ImageTy->getNumOperands() > 8)
@@ -92,61 +126,90 @@ inline IRHandle make_descr_sampled_image(const Type *SampledTy,
SpecialTypeKind::STK_SampledImage);
}
-inline IRHandle make_descr_sampler() {
+inline IRHandle irhandle_sampler() {
return std::make_tuple(nullptr, 0U, SpecialTypeKind::STK_Sampler);
}
-inline IRHandle make_descr_pipe(uint8_t AQ) {
+inline IRHandle irhandle_pipe(uint8_t AQ) {
return std::make_tuple(nullptr, AQ, SpecialTypeKind::STK_Pipe);
}
-inline IRHandle make_descr_event() {
+inline IRHandle irhandle_event() {
return std::make_tuple(nullptr, 0U, SpecialTypeKind::STK_DeviceEvent);
}
-inline IRHandle make_descr_pointee(const Type *ElementType,
- unsigned AddressSpace) {
- return std::make_tuple(ElementType, AddressSpace,
+inline IRHandle irhandle_pointee(const Type *ElementType,
+ unsigned AddressSpace) {
+ return std::make_tuple(unifyPtrType(ElementType), AddressSpace,
SpecialTypeKind::STK_ElementPointer);
}
-inline IRHandle make_descr_ptr(const void *Ptr, unsigned Arg = 0U) {
- return std::make_tuple(Ptr, Arg, SpecialTypeKind::STK_Pointer);
+inline IRHandle irhandle_ptr(const void *Ptr, unsigned Arg,
+ enum SpecialTypeKind STK) {
+ return std::make_tuple(Ptr, Arg, STK);
+}
+
+inline IRHandle handle(const Type *Ty) {
+ const Type *WrpTy = unifyPtrType(Ty);
+ return irhandle_ptr(WrpTy, Ty->getTypeID(), STK_Type);
}
+
+inline IRHandle handle(const Value *V) {
+ return irhandle_ptr(V, V->getValueID(), STK_Value);
+}
+
+inline IRHandle handle(const MachineInstr *KeyMI) {
+ return irhandle_ptr(KeyMI, SPIRV::to_hash(KeyMI), STK_MachineInstr);
+}
+
} // namespace SPIRV
// Bi-directional mappings between LLVM entities and (v-reg, machine function)
// pairs support management of unique SPIR-V definitions per machine function
// per an LLVM/GlobalISel entity (e.g., Type, Constant, Machine Instruction).
class SPIRVIRMapping {
- DenseMap<std::pair<SPIRV::IRHandle, const MachineFunction *>,
- const MachineInstr *>
- Vregs;
- DenseMap<const MachineInstr *, SPIRV::IRHandle> Defs;
+ DenseMap<SPIRV::IRHandleMF, SPIRV::MIHandle> Vregs;
+ DenseMap<SPIRV::MIHandle, SPIRV::IRHandle> Defs;
public:
bool add(SPIRV::IRHandle Handle, const MachineInstr *MI) {
+ if (std::get<1>(Handle) == 17 && std::get<2>(Handle) == 8) {
+ const Value *Ptr = (const Value *)std::get<0>(Handle);
+ if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Ptr)) {
+ if (CI->getZExtValue() == 8 || CI->getZExtValue() == 5) {
+ [[maybe_unused]] uint64_t v = CI->getZExtValue();
+ }
+ }
+ }
+ auto MIKey = SPIRV::getMIKey(MI);
auto [It, Inserted] =
- Vregs.try_emplace(std::make_pair(Handle, MI->getMF()), MI);
+ Vregs.try_emplace(std::make_pair(Handle, MI->getMF()), MIKey);
if (Inserted) {
- auto [_, IsConsistent] = Defs.insert_or_assign(MI, Handle);
+ [[maybe_unused]] auto [_, IsConsistent] =
+ Defs.insert_or_assign(MIKey, Handle);
assert(IsConsistent);
}
return Inserted;
}
bool erase(const MachineInstr *MI) {
bool Res = false;
- if (auto It = Defs.find(MI); It != Defs.end()) {
- Res = Vregs.erase(std::make_pair(It->second, MI->getMF()));
+ if (auto It = Defs.find(SPIRV::getMIKey(MI)); It != Defs.end()) {
+ Res = Vregs.erase(SPIRV::getIRHandleMF(It->second, MI->getMF()));
Defs.erase(It);
}
return Res;
}
const MachineInstr *findMI(SPIRV::IRHandle Handle,
const MachineFunction *MF) {
- if (auto It = Vregs.find(std::make_pair(Handle, MF)); It != Vregs.end())
- return It->second;
- return nullptr;
+ auto It = Vregs.find(SPIRV::getIRHandleMF(Handle, MF));
+ if (It == Vregs.end())
+ return nullptr;
+ auto [MI, Hash] = It->second;
+ if (SPIRV::to_hash(MI) != Hash) {
+ erase(MI);
+ return nullptr;
+ }
+ return MI;
}
Register find(SPIRV::IRHandle Handle, const MachineFunction *MF) {
const MachineInstr *MI = findMI(Handle, MF);
@@ -154,38 +217,28 @@ class SPIRVIRMapping {
}
// helpers
- bool add(const Type *Ty, const MachineInstr *MI) {
- return add(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MI);
- }
- bool add(const void *Key, const MachineInstr *MI) {
- return add(SPIRV::make_descr_ptr(Key), MI);
- }
bool add(const Type *PointeeTy, unsigned AddressSpace,
const MachineInstr *MI) {
- return add(SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace),
- MI);
- }
- Register find(const Type *Ty, const MachineFunction *MF) {
- return find(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MF);
- }
- const MachineInstr *findMI(const Type *Ty, const MachineFunction *MF) {
- return findMI(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MF);
- }
- Register find(const void *Key, const MachineFunction *MF) {
- return find(SPIRV::make_descr_ptr(Key), MF);
- }
- const MachineInstr *findMI(const void *Key, const MachineFunction *MF) {
- return findMI(SPIRV::make_descr_ptr(Key), MF);
+ return add(SPIRV::irhandle_pointee(PointeeTy, AddressSpace), MI);
}
Register find(const Type *PointeeTy, unsigned AddressSpace,
const MachineFunction *MF) {
- return find(
- SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace), MF);
+ return find(SPIRV::irhandle_pointee(PointeeTy, AddressSpace), MF);
}
const MachineInstr *findMI(const Type *PointeeTy, unsigned AddressSpace,
const MachineFunction *MF) {
- return findMI(
- SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace), MF);
+ return findMI(SPIRV::irhandle_pointee(PointeeTy, AddressSpace), MF);
+ }
+
+ template <typename T> bool add(const T *Obj, const MachineInstr *MI) {
+ return add(SPIRV::handle(Obj), MI);
+ }
+ template <typename T> Register find(const T *Obj, const MachineFunction *MF) {
+ return find(SPIRV::handle(Obj), MF);
+ }
+ template <typename T>
+ const MachineInstr *findMI(const T *Obj, const MachineFunction *MF) {
+ return findMI(SPIRV::handle(Obj), MF);
}
};
} // namespace llvm
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
index a8f862271dbab..4b9bddd661f63 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
@@ -15,6 +15,7 @@ include "SPIRVSymbolicOperands.td"
// Codegen only metadata instructions
let isCodeGenOnly=1 in {
+ def TYPEREF: Pseudo<(outs), (ins ID:$src_id, TYPE:$src_ty)>;
def ASSIGN_TYPE: Pseudo<(outs ID:$dst_id), (ins ID:$src_id, TYPE:$src_ty)>;
def DECL_TYPE: Pseudo<(outs ID:$dst_id), (ins ID:$src_id, TYPE:$src_ty)>;
def GET_ID: Pseudo<(outs iID:$dst_id), (ins iID:$src)>;
@@ -28,8 +29,10 @@ let isCodeGenOnly=1 in {
def SPVTypeBin : SDTypeProfile<1, 2, []>;
def assigntype : SDNode<"SPIRVISD::AssignType", SPVTypeBin>;
+def typeref : SDNode<"SPIRVISD::TypeRef", SPVTypeBin>;
def : GINodeEquiv<ASSIGN_TYPE, assigntype>;
+def : GINodeEquiv<TYPEREF, typeref>;
class BinOp<string name, bits<16> opCode, list<dag> pattern=[]>
: Op<opCode, (outs ID:$dst), (ins TYPE:$src_ty, ID:$src, ID:$src2),
@@ -472,11 +475,8 @@ def OpConvertBF16ToFINTEL : UnOp<"OpConvertBF16ToFINTEL", 6117>;
// 3.42.12 Composite Instructions
-//def OpVectorExtractDynamic: Op<77, (outs ID:$res), (ins TYPE:$type, vID:$vec, ID:$idx),
-// "$res = OpVectorExtractDynamic $type $vec $idx", [(set ID:$res, (assigntype (extractelt vID:$vec, ID:$idx), TYPE:$type))]>;
def OpVectorExtractDynamic: Op<77, (outs ID:$res), (ins TYPE:$type, vID:$vec, ID:$idx),
"$res = OpVectorExtractDynamic $type $vec $idx">;
-
def OpVectorInsertDynamic: Op<78, (outs ID:$res), (ins TYPE:$ty, ID:$vec, ID:$comp, ID:$idx),
"$res = OpVectorInsertDynamic $ty $vec $comp $idx">;
def OpVectorShuffle: Op<79, (outs ID:$res), (ins TYPE:$ty, ID:$v1, ID:$v2, variable_ops),
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index aa82f7f7d936a..8f1ac07dd9450 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -393,27 +393,84 @@ void SPIRVInstructionSelector::resetVRegsType(MachineFunction &MF) {
}
for (const auto &MBB : MF) {
for (const auto &MI : MBB) {
- if (MI.getOpcode() != SPIRV::ASSIGN_TYPE)
- continue;
- Register DstReg = MI.getOperand(0).getReg();
- LLT DstType = MRI.getType(DstReg);
- Register SrcReg = MI.getOperand(1).getReg();
- LLT SrcType = MRI.getType(SrcReg);
- if (DstType != SrcType)
- MRI.setType(DstReg, MRI.getType(SrcReg));
-
- const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(DstReg);
- const TargetRegisterClass *SrcRC = MRI.getRegClassOrNull(SrcReg);
- if (DstRC != SrcRC && SrcRC)
- MRI.setRegClass(DstReg, SrcRC);
+ if (MI.getOpcode() == SPIRV::ASSIGN_TYPE) {
+ Register DstReg = MI.getOperand(0).getReg();
+ LLT DstType = MRI.getType(DstReg);
+ Register SrcReg = MI.getOperand(1).getReg();
+ LLT SrcType = MRI.getType(SrcReg);
+ if (DstType != SrcType)
+ MRI.setType(DstReg, MRI.getType(SrcReg));
+
+ const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(DstReg);
+ const TargetRegisterClass *SrcRC = MRI.getRegClassOrNull(SrcReg);
+ if (DstRC != SrcRC && SrcRC)
+ MRI.setRegClass(DstReg, SrcRC);
+ } else if (MI.getOpcode() == SPIRV::TYPEREF) {
+ Register DstReg = MI.getOperand(0).getReg();
+ LLT DstType = MRI.getType(DstReg);
+ Register SrcReg = MI.getOperand(1).getReg();
+ LLT SrcType = MRI.getType(SrcReg);
+ if (DstType != SrcType)
+ MRI.setType(DstReg, MRI.getType(SrcReg));
+ }
}
}
}
-static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI);
+// Return true if the type represents a constant register
+static bool isConstReg(MachineRegisterInfo *MRI, MachineInstr *OpDef,
+ SmallPtrSet<SPIRVType *, 4> &Visited) {
+ OpDef = passCopy(OpDef, MRI);
+
+ if (Visited.contains(OpDef))
+ return true;
+ Visited.insert(OpDef);
+
+ unsigned Opcode = OpDef->getOpcode();
+ switch (Opcode) {
+ case TargetOpcode::G_CONSTANT:
+ case TargetOpcode::G_FCONSTANT:
+ return true;
+ case TargetOpcode::G_INTRINSIC:
+ case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
+ case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
+ return cast<GIntrinsic>(*OpDef).getIntrinsicID() ==
+ Intrinsic::spv_const_composite;
+ case TargetOpcode::G_BUILD_VECTOR:
+ case TargetOpcode::G_SPLAT_VECTOR: {
+ for (unsigned i = OpDef->getNumExplicitDefs(); i < OpDef->getNumOperands();
+ i++) {
+ MachineInstr *OpNestedDef =
+ OpDef->getOperand(i).isReg()
+ ? MRI->getVRegDef(OpDef->getOperand(i).getReg())
+ : nullptr;
+ if (OpNestedDef && !isConstReg(MRI, OpNestedDef, Visited))
+ return false;
+ }
+ return true;
+ case SPIRV::OpConstantTrue:
+ case SPIRV::OpConstantFalse:
+ case SPIRV::OpConstantI:
+ case SPIRV::OpConstantF:
+ case SPIRV::OpConstantComposite:
+ case SPIRV::OpConstantCompositeContinuedINTEL:
+ case SPIRV::OpConstantSampler:
+ case SPIRV::OpConstantNull:
+ case SPIRV::OpUndef:
+ case SPIRV::OpConstantFunctionPointerINTEL:
+ return true;
+ }
+ }
+ return false;
+}
-// Defined in SPIRVLegalizerInfo.cpp.
-extern bool isTypeFoldingSupported(unsigned Opcode);
+// Return true if the virtual register represents a constant
+static bool isConstReg(MachineRegisterInfo *MRI, Register OpReg) {
+ SmallPtrSet<SPIRVType *, 4> Visited;
+ if (MachineInstr *OpDef = MRI->getVRegDef(OpReg))
+ return isConstReg(MRI, OpDef, Visited);
+ return false;
+}
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI) {
for (const auto &MO : MI.all_defs()) {
@@ -466,6 +523,27 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
GR.invalidateMachineInstr(&I);
I.removeFromParent();
return true;
+ } else if (Opcode == SPIRV::TYPEREF) {
+ Register SrcReg = I.getOperand(0).getReg();
+ auto *Def = MRI->getVRegDef(SrcReg);
+ if (isTypeFoldingSupported(Def->getOpcode())) {
+ bool Res = selectImpl(I, *CoverageInfo);
+ LLVM_DEBUG({
+ if (!Res && Def->getOpcode() != TargetOpcode::G_CONSTANT) {
+ dbgs() << "Unexpected pattern in ASSIGN_TYPE.\nInstruction: ";
+ I.print(dbgs());
+ }
+ });
+ assert(Res || Def->getOpcode() == TargetOpcode::G_CONSTANT);
+ if (Res) {
+ if (!isTriviallyDead(*Def, *MRI) && isDead(*Def, *MRI))
+ DeadMIs.insert(Def);
+ return Res;
+ }
+ }
+ GR.invalidateMachineInstr(&I);
+ I.removeFromParent();
+ return true;
} else if (I.getNumDefs() == 1) {
// Make all vregs 64 bits (for SPIR-V IDs).
MRI->setType(I.getOperand(0).getReg(), LLT::scalar(64));
@@ -766,7 +844,7 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
assert(((*II).getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
(*II).getOpcode() == TargetOpcode::COPY ||
(*II).getOpcode() == SPIRV::OpVariable) &&
- isImm(I.getOperand(2), MRI));
+ getImm(I.getOperand(2), MRI));
// It may be the initialization of a global variable.
bool IsGVInit = false;
for (MachineRegisterInfo::use_instr_iterator
@@ -2003,27 +2081,30 @@ bool SPIRVInstructionSelector::selectDot4AddPackedExpansion(
auto ExtractOp =
Signed ? SPIRV::OpBitFieldSExtract : SPIRV::OpBitFieldUExtract;
+ bool ZeroAsNull = STI.isOpenCLEnv();
// Extract the i8 element, multiply and add it to the accumulator
for (unsigned i = 0; i < 4; i++) {
// A[i]
Register AElt = MRI->createVirtualRegister(&SPIRV::IDRegClass);
- Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
- .addDef(AElt)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addUse(I.getOperand(2).getReg())
- .addUse(GR.getOrCreateConstInt(i * 8, I, EltType, TII))
- .addUse(GR.getOrCreateConstInt(8, I, EltType, TII))
- .constrainAllUses(TII, TRI, RBI);
+ Result &=
+ BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
+ .addDef(AElt)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(I.getOperand(2).getReg())
+ .addUse(GR.getOrCreateConstInt(i * 8, I, EltType, TII, ZeroAsNull))
+ .addUse(GR.getOrCreateConstInt(8, I, EltType, TII, ZeroAsNull))
+ .constrainAllUses(TII, TRI, RBI);
// B[i]
Register BElt = MRI->createVirtualRegister(&SPIRV::IDRegClass);
- Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
- .addDef(BElt)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addUse(I.getOperand(3).getReg())
- .addUse(GR.getOrCreateConstInt(i * 8, I, EltType, TII))
- .addUse(GR.getOrCreateConstInt(8, I, EltType, TII))
- .constrainAllUses(TII, TRI, RBI);
+ Result &=
+ BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
+ .addDef(BElt)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(I.getOperand(3).getReg())
+ .addUse(GR.getOrCreateConstInt(i * 8, I, EltType, TII, ZeroAsNull))
+ .addUse(GR.getOrCreateConstInt(8, I, EltType, TII, ZeroAsNull))
+ .constrainAllUses(TII, TRI, RBI);
// A[i] * B[i]
Register Mul = MRI->createVirtualRegister(&SPIRV::IDRegClass);
@@ -2036,13 +2117,14 @@ bool SPIRVInstructionSelector::selectDot4AddPackedExpansion(
// Discard 24 highest-bits so that stored i32 register is i8 equivalent
Register MaskMul = MRI->createVirtualRegister(&SPIRV::IDRegClass);
- Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
- .addDef(MaskMul)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addUse(Mul)
- .addUse(GR.getOrCreateConstInt(0, I, EltType, TII))
- .addUse(GR.getOrCreateConstInt(8, I, EltType, TII))
- .constrainAllUses(TII, TRI, RBI);
+ Result &=
+ BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
+ .addDef(MaskMul)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(Mul)
+ .addUse(GR.getOrCreateConstInt(0, I, EltType, TII, ZeroAsNull))
+ .addUse(GR.getOrCreateConstInt(8, I, EltType, TII, ZeroAsNull))
+ .constrainAllUses(TII, TRI, RBI);
// Acc = Acc + A[i] * B[i]
Register Sum =
@@ -2139,7 +2221,7 @@ bool SPIRVInstructionSelector::selectWaveOpInst(Register ResVReg,
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
.addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I,
- IntTy, TII));
+ IntTy, TII, STI.isOpenCLEnv()));
for (unsigned J = 2; J < I.getNumOperands(); J++) {
BMI.addUse(I.getOperand(J).getReg());
@@ -2158,15 +2240,15 @@ bool SPIRVInstructionSelector::selectWaveActiveCountBits(
SPIRV::OpGroupNonUniformBallot);
MachineBasicBlock &BB = *I.getParent();
- Result &=
- BuildMI(BB, I, I.getDebugLoc(),
- TII.get(SPIRV::OpGroupNonUniformBallotBitCount))
- .addDef(ResVReg)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII))
- .addImm(SPIRV::GroupOperation::Reduce)
- .addUse(BallotReg)
- .constrainAllUses(TII, TRI, RBI);
+ Result &= BuildMI(BB, I, I.getDebugLoc(),
+ TII.get(SPIRV::OpGroupNonUniformBallotBitCount))
+ .addDef(ResVReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy,
+ TII, STI.isOpenCLEnv()))
+ .addImm(SPIRV::GroupOperation::Reduce)
+ .addUse(BallotReg)
+ .constrainAllUses(TII, TRI, RBI);
return Result;
}
@@ -2193,7 +2275,8 @@ bool SPIRVInstructionSelector::selectWaveReduceMax(Register ResVReg,
return BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
- .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII))
+ .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII,
+ STI.isOpenCLEnv()))
.addImm(SPIRV::GroupOperation::Reduce)
.addUse(I.getOperand(2).getReg())
.constrainAllUses(TII, TRI, RBI);
@@ -2219,7 +2302,8 @@ bool SPIRVInstructionSelector::selectWaveReduceSum(Register ResVReg,
return BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
- .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII))
+ .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII,
+ STI.isOpenCLEnv()))
.addImm(SPIRV::GroupOperation::Reduce)
.addUse(I.getOperand(2).getReg());
}
@@ -2247,6 +2331,8 @@ bool SPIRVInstructionSelector::selectFreeze(Register ResVReg,
return false;
Register OpReg = I.getOperand(1).getReg();
if (MachineInstr *Def = MRI->getVRegDef(OpReg)) {
+ if (Def->getOpcode() == TargetOpcode::COPY)
+ Def = MRI->getVRegDef(Def->getOperand(1).getReg());
Register Reg;
switch (Def->getOpcode()) {
case SPIRV::ASSIGN_TYPE:
@@ -2275,82 +2361,6 @@ bool SPIRVInstructionSelector::selectFreeze(Register ResVReg,
return false;
}
-static unsigned getArrayComponentCount(MachineRegisterInfo *MRI,
- const SPIRVType *ResType) {
- Register OpReg = ResType->getOperand(2).getReg();
- SPIRVType *OpDef = MRI->getVRegDef(OpReg);
- if (!OpDef)
- return 0;
- if (OpDef->getOpcode() == SPIRV::ASSIGN_TYPE &&
- OpDef->getOperand(1).isReg()) {
- if (SPIRVType *RefDef = MRI->getVRegDef(OpDef->getOperand(1).getReg()))
- OpDef = RefDef;
- }
- unsigned N = OpDef->getOpcode() == TargetOpcode::G_CONSTANT
- ? OpDef->getOperand(1).getCImm()->getValue().getZExtValue()
- : 0;
- return N;
-}
-
-// Return true if the type represents a constant register
-static bool isConstReg(MachineRegisterInfo *MRI, SPIRVType *OpDef,
- SmallPtrSet<SPIRVType *, 4> &Visited) {
- if (OpDef->getOpcode() == SPIRV::ASSIGN_TYPE &&
- OpDef->getOperand(1).isReg()) {
- if (SPIRVType *RefDef = MRI->getVRegDef(OpDef->getOperand(1).getReg()))
- OpDef = RefDef;
- }
-
- if (Visited.contains(OpDef))
- return true;
- Visited.insert(OpDef);
-
- unsigned Opcode = OpDef->getOpcode();
- switch (Opcode) {
- case TargetOpcode::G_CONSTANT:
- case TargetOpcode::G_FCONSTANT:
- return true;
- case TargetOpcode::G_INTRINSIC:
- case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
- case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
- return cast<GIntrinsic>(*OpDef).getIntrinsicID() ==
- Intrinsic::spv_const_composite;
- case TargetOpcode::G_BUILD_VECTOR:
- case TargetOpcode::G_SPLAT_VECTOR: {
- for (unsigned i = OpDef->getNumExplicitDefs(); i < OpDef->getNumOperands();
- i++) {
- SPIRVType *OpNestedDef =
- OpDef->getOperand(i).isReg()
- ? MRI->getVRegDef(OpDef->getOperand(i).getReg())
- : nullptr;
- if (OpNestedDef && !isConstReg(MRI, OpNestedDef, Visited))
- return false;
- }
- return true;
- case SPIRV::OpConstantTrue:
- case SPIRV::OpConstantFalse:
- case SPIRV::OpConstantI:
- case SPIRV::OpConstantF:
- case SPIRV::OpConstantComposite:
- case SPIRV::OpConstantCompositeContinuedINTEL:
- case SPIRV::OpConstantSampler:
- case SPIRV::OpConstantNull:
- case SPIRV::OpUndef:
- case SPIRV::OpConstantFunctionPointerINTEL:
- return true;
- }
- }
- return false;
-}
-
-// Return true if the virtual register represents a constant
-static bool isConstReg(MachineRegisterInfo *MRI, Register OpReg) {
- SmallPtrSet<SPIRVType *, 4> Visited;
- if (SPIRVType *OpDef = MRI->getVRegDef(OpReg))
- return isConstReg(MRI, OpDef, Visited);
- return false;
-}
-
bool SPIRVInstructionSelector::selectBuildVector(Register ResVReg,
const SPIRVType *ResType,
MachineInstr &I) const {
@@ -2740,7 +2750,15 @@ bool SPIRVInstructionSelector::selectConst(Register ResVReg,
.constrainAllUses(TII, TRI, RBI);
if (TyOpcode == SPIRV::OpTypeInt) {
assert(Imm.getBitWidth() <= 64 && "Unsupported integer width!");
- Register Reg = GR.getOrCreateConstInt(Imm.getZExtValue(), I, ResType, TII);
+ const ConstantInt *CI =
+ ConstantInt::get(const_cast<IntegerType *>(cast<IntegerType>(
+ GR.getTypeForSPIRVType(ResType))),
+ Imm.getZExtValue());
+ const MachineInstr *ConstMI = GR.findMI(CI, GR.CurMF);
+ Register Reg =
+ (ConstMI && ConstMI != &I)
+ ? ConstMI->getOperand(0).getReg()
+ : GR.createConstInt(CI, I, ResType, TII, STI.isOpenCLEnv());
return Reg == ResVReg ? true : BuildCOPY(ResVReg, Reg, I);
}
auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantI))
@@ -2761,25 +2779,6 @@ bool SPIRVInstructionSelector::selectOpUndef(Register ResVReg,
.constrainAllUses(TII, TRI, RBI);
}
-static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI) {
- assert(MO.isReg());
- const SPIRVType *TypeInst = MRI->getVRegDef(MO.getReg());
- 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();
-}
bool SPIRVInstructionSelector::selectInsertVal(Register ResVReg,
const SPIRVType *ResType,
@@ -2813,7 +2812,7 @@ bool SPIRVInstructionSelector::selectExtractVal(Register ResVReg,
bool SPIRVInstructionSelector::selectInsertElt(Register ResVReg,
const SPIRVType *ResType,
MachineInstr &I) const {
- if (isImm(I.getOperand(4), MRI))
+ if (getImm(I.getOperand(4), MRI))
return selectInsertVal(ResVReg, ResType, I);
MachineBasicBlock &BB = *I.getParent();
return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpVectorInsertDynamic))
@@ -2828,7 +2827,7 @@ bool SPIRVInstructionSelector::selectInsertElt(Register ResVReg,
bool SPIRVInstructionSelector::selectExtractElt(Register ResVReg,
const SPIRVType *ResType,
MachineInstr &I) const {
- if (isImm(I.getOperand(3), MRI))
+ if (getImm(I.getOperand(3), MRI))
return selectExtractVal(ResVReg, ResType, I);
MachineBasicBlock &BB = *I.getParent();
return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpVectorExtractDynamic))
@@ -2875,7 +2874,7 @@ bool SPIRVInstructionSelector::wrapIntoSpecConstantOp(
unsigned Lim = I.getNumExplicitOperands();
for (unsigned i = I.getNumExplicitDefs() + 1; i < Lim; ++i) {
Register OpReg = I.getOperand(i).getReg();
- SPIRVType *OpDefine = MRI->getVRegDef(OpReg);
+ MachineInstr *OpDefine = MRI->getVRegDef(OpReg);
SPIRVType *OpType = GR.getSPIRVTypeForVReg(OpReg);
SmallPtrSet<SPIRVType *, 4> Visited;
if (!OpDefine || !OpType || isConstReg(MRI, OpDefine, Visited) ||
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
index daa8ea52ffe03..520ea169fd638 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
@@ -24,43 +24,6 @@ using namespace llvm;
using namespace llvm::LegalizeActions;
using namespace llvm::LegalityPredicates;
-// clang-format off
-static const std::set<unsigned> TypeFoldingSupportingOpcs = {
- TargetOpcode::G_ADD,
- TargetOpcode::G_FADD,
- TargetOpcode::G_STRICT_FADD,
- TargetOpcode::G_SUB,
- TargetOpcode::G_FSUB,
- TargetOpcode::G_STRICT_FSUB,
- TargetOpcode::G_MUL,
- TargetOpcode::G_FMUL,
- TargetOpcode::G_STRICT_FMUL,
- TargetOpcode::G_SDIV,
- TargetOpcode::G_UDIV,
- TargetOpcode::G_FDIV,
- TargetOpcode::G_STRICT_FDIV,
- TargetOpcode::G_SREM,
- TargetOpcode::G_UREM,
- TargetOpcode::G_FREM,
- TargetOpcode::G_STRICT_FREM,
- TargetOpcode::G_FNEG,
- TargetOpcode::G_CONSTANT,
- TargetOpcode::G_FCONSTANT,
- TargetOpcode::G_AND,
- TargetOpcode::G_OR,
- TargetOpcode::G_XOR,
- TargetOpcode::G_SHL,
- TargetOpcode::G_ASHR,
- TargetOpcode::G_LSHR,
- TargetOpcode::G_SELECT,
- TargetOpcode::G_EXTRACT_VECTOR_ELT,
-};
-// clang-format on
-
-bool isTypeFoldingSupported(unsigned Opcode) {
- return TypeFoldingSupportingOpcs.count(Opcode) > 0;
-}
-
LegalityPredicate typeOfExtendedScalars(unsigned TypeIdx, bool IsExtendedInts) {
return [IsExtendedInts, TypeIdx](const LegalityQuery &Query) {
const LLT Ty = Query.Types[TypeIdx];
@@ -181,7 +144,7 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
return IsExtendedInts && Ty.isValid();
};
- for (auto Opc : TypeFoldingSupportingOpcs)
+ for (auto Opc : getTypeFoldingSupportedOpcodes())
getActionDefinitionsBuilder(Opc).custom();
getActionDefinitionsBuilder(G_GLOBAL_VALUE).alwaysLegal();
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.h b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.h
index f18b15b7f1696..6335f211e1986 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.h
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.h
@@ -16,8 +16,6 @@
#include "SPIRVGlobalRegistry.h"
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
-bool isTypeFoldingSupported(unsigned Opcode);
-
namespace llvm {
class LLVMContext;
diff --git a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
index e7b942e42b0a2..4c20688e9e983 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
@@ -41,15 +41,11 @@ class SPIRVPostLegalizer : public MachineFunctionPass {
};
} // namespace
-// Defined in SPIRVLegalizerInfo.cpp.
-extern bool isTypeFoldingSupported(unsigned Opcode);
-
namespace llvm {
// Defined in SPIRVPreLegalizer.cpp.
-extern Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
- SPIRVGlobalRegistry *GR,
- MachineIRBuilder &MIB,
- MachineRegisterInfo &MRI);
+extern void insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
+ SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB,
+ MachineRegisterInfo &MRI);
extern void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR);
} // namespace llvm
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index da837c9ed85dd..0ece31ee88abe 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -98,7 +98,8 @@ addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
SrcMI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF))
TargetExtConstTypes[SrcMI] = Const->getType();
if (Const->isNullValue()) {
- MachineIRBuilder MIB(MF);
+ MachineBasicBlock &DepMBB = MF.front();
+ MachineIRBuilder MIB(DepMBB, DepMBB.getFirstNonPHI());
SPIRVType *ExtType = GR->getOrCreateSPIRVType(
Const->getType(), MIB, SPIRV::AccessQualifier::ReadWrite,
true);
@@ -128,13 +129,17 @@ addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
if (!MRI.getRegClassOrNull(Reg) && RC)
MRI.setRegClass(Reg, RC);
MRI.replaceRegWith(MI->getOperand(0).getReg(), Reg);
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
}
- for (MachineInstr *MI : ToEraseComposites)
+ for (MachineInstr *MI : ToEraseComposites) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
}
static void foldConstantsIntoIntrinsics(MachineFunction &MF,
+ SPIRVGlobalRegistry *GR,
MachineIRBuilder MIB) {
SmallVector<MachineInstr *, 64> ToErase;
for (MachineBasicBlock &MBB : MF) {
@@ -149,8 +154,10 @@ static void foldConstantsIntoIntrinsics(MachineFunction &MF,
}
ToErase.push_back(&MI);
}
- for (MachineInstr *MI : ToErase)
+ for (MachineInstr *MI : ToErase) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
ToErase.clear();
}
}
@@ -219,8 +226,10 @@ static void selectOpBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR,
ToErase.push_back(&MI);
}
}
- for (MachineInstr *MI : ToErase)
+ for (MachineInstr *MI : ToErase) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
}
static void insertBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR,
@@ -264,8 +273,10 @@ static void insertBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR,
}
}
}
- for (MachineInstr *MI : ToErase)
+ for (MachineInstr *MI : ToErase) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
}
// Translating GV, IRTranslator sometimes generates following IR:
@@ -384,7 +395,7 @@ static void widenScalarLLTNextPow2(Register Reg, MachineRegisterInfo &MRI) {
if (NewSz != Sz)
MRI.setType(Reg, LLT::scalar(NewSz));
}
-
+/*
static std::pair<Register, unsigned>
createNewIdReg(SPIRVType *SpvType, Register SrcReg, MachineRegisterInfo &MRI,
const SPIRVGlobalRegistry &GR) {
@@ -406,7 +417,7 @@ createNewIdReg(SPIRVType *SpvType, Register SrcReg, MachineRegisterInfo &MRI,
GetIdOp = SPIRV::GET_vID;
return {Reg, GetIdOp};
}
-
+*/
static void setInsertPtAfterDef(MachineIRBuilder &MIB, MachineInstr *Def) {
MachineBasicBlock &MBB = *Def->getParent();
MachineBasicBlock::iterator DefIt =
@@ -418,21 +429,31 @@ static void setInsertPtAfterDef(MachineIRBuilder &MIB, MachineInstr *Def) {
MIB.setInsertPt(MBB, DefIt);
}
-// Insert ASSIGN_TYPE instuction between Reg and its definition, set NewReg as
-// a dst of the definition, assign SPIRVType to both registers. If SpvType is
-// provided, use it as SPIRVType in ASSIGN_TYPE, otherwise create it from Ty.
-// It's used also in SPIRVBuiltins.cpp.
-// TODO: maybe move to SPIRVUtils.
namespace llvm {
-Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpvType,
- SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB,
- MachineRegisterInfo &MRI) {
+void insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpvType,
+ SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB,
+ MachineRegisterInfo &MRI) {
assert((Ty || SpvType) && "Either LLVM or SPIRV type is expected.");
MachineInstr *Def = MRI.getVRegDef(Reg);
setInsertPtAfterDef(MIB, Def);
- SpvType = SpvType ? SpvType
- : GR->getOrCreateSPIRVType(
- Ty, MIB, SPIRV::AccessQualifier::ReadWrite, true);
+ if (!SpvType)
+ SpvType = GR->getOrCreateSPIRVType(Ty, MIB,
+ SPIRV::AccessQualifier::ReadWrite, true);
+
+ if (!isTypeFoldingSupported(Def->getOpcode())) {
+ // No need to generate SPIRV::ASSIGN_TYPE pseudo-instruction
+ if (!GR->getSPIRVTypeForVReg(Reg, &MRI.getMF())) {
+ if (!MRI.getRegClassOrNull(Reg))
+ MRI.setRegClass(Reg, GR->getRegClass(SpvType));
+ if (!MRI.getType(Reg).isValid())
+ MRI.setType(Reg, GR->getRegType(SpvType));
+ GR->assignSPIRVTypeToVReg(SpvType, Reg, MIB.getMF());
+ }
+ return;
+ }
+
+ // Tablegen definition assumes SPIRV::ASSIGN_TYPE pseudo-instruction is
+ // present after each auto-folded instruction to take a type reference from.
Register NewReg = MRI.createGenericVirtualRegister(MRI.getType(Reg));
if (auto *RC = MRI.getRegClassOrNull(Reg)) {
MRI.setRegClass(NewReg, RC);
@@ -460,12 +481,27 @@ Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpvType,
break;
}
}
- return NewReg;
}
void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR) {
MIB.setInsertPt(*MI.getParent(), MI.getIterator());
+ for (auto &Op : MI.operands()) {
+ if (!Op.isReg() || Op.isDef())
+ continue;
+ Register OpReg = Op.getReg();
+ SPIRVType *SpvType = GR->getSPIRVTypeForVReg(OpReg);
+ assert(SpvType);
+ if (!MRI.getRegClassOrNull(OpReg))
+ MRI.setRegClass(OpReg, GR->getRegClass(SpvType));
+ if (!MRI.getType(OpReg).isValid())
+ MRI.setType(OpReg, GR->getRegType(SpvType));
+ }
+}
+
+/*void processInstr2(MachineInstr &MI, MachineIRBuilder &MIB,
+ MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR) {
+ MIB.setInsertPt(*MI.getParent(), MI.getIterator());
for (auto &Op : MI.operands()) {
if (!Op.isReg() || Op.isDef())
continue;
@@ -478,7 +514,7 @@ void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
MRI.setRegClass(OpReg, RC);
Op.setReg(IdOpInfo.first);
}
-}
+}*/
} // namespace llvm
static void
@@ -528,7 +564,8 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
assert(Def && "Expecting an instruction that defines the register");
// G_GLOBAL_VALUE already has type info.
if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
- Def->getOpcode() != SPIRV::ASSIGN_TYPE)
+ Def->getOpcode() != SPIRV::ASSIGN_TYPE &&
+ Def->getOpcode() != SPIRV::TYPEREF)
insertAssignInstr(Reg, nullptr, AssignedPtrType, GR, MIB,
MF.getRegInfo());
ToErase.push_back(&MI);
@@ -539,7 +576,8 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
assert(Def && "Expecting an instruction that defines the register");
// G_GLOBAL_VALUE already has type info.
if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
- Def->getOpcode() != SPIRV::ASSIGN_TYPE)
+ Def->getOpcode() != SPIRV::ASSIGN_TYPE &&
+ Def->getOpcode() != SPIRV::TYPEREF)
insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MF.getRegInfo());
ToErase.push_back(&MI);
} else if (MIOp == TargetOpcode::FAKE_USE && MI.getNumOperands() > 0) {
@@ -576,7 +614,8 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
if (isSpvIntrinsic(UseMI, Intrinsic::spv_assign_type) ||
isSpvIntrinsic(UseMI, Intrinsic::spv_assign_name))
continue;
- if (UseMI.getOpcode() == SPIRV::ASSIGN_TYPE)
+ if (UseMI.getOpcode() == SPIRV::ASSIGN_TYPE ||
+ UseMI.getOpcode() == SPIRV::TYPEREF)
NeedAssignType = false;
}
Type *Ty = nullptr;
@@ -620,11 +659,18 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
} else if (ElemMI->getOpcode() == TargetOpcode::G_FCONSTANT) {
ElemTy = ElemMI->getOperand(1).getFPImm()->getType();
} else {
- // There may be a case when we already know Reg's type.
- MachineInstr *NextMI = MI.getNextNode();
- if (!NextMI || NextMI->getOpcode() != SPIRV::ASSIGN_TYPE ||
- NextMI->getOperand(1).getReg() != Reg)
- llvm_unreachable("Unexpected opcode");
+ if (const SPIRVType *ElemSpvType =
+ GR->getSPIRVTypeForVReg(MI.getOperand(1).getReg(), &MF))
+ ElemTy = const_cast<Type *>(GR->getTypeForSPIRVType(ElemSpvType));
+ if (!ElemTy) {
+ // There may be a case when we already know Reg's type.
+ MachineInstr *NextMI = MI.getNextNode();
+ if (!NextMI ||
+ (NextMI->getOpcode() != SPIRV::ASSIGN_TYPE &&
+ NextMI->getOpcode() != SPIRV::TYPEREF) ||
+ NextMI->getOperand(1).getReg() != Reg)
+ llvm_unreachable("Unexpected opcode");
+ }
}
if (ElemTy)
Ty = VectorType::get(
@@ -649,6 +695,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
auto It = RegsAlreadyAddedToDT.find(MI);
if (It != RegsAlreadyAddedToDT.end())
MRI.replaceRegWith(MI->getOperand(0).getReg(), It->second);
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
}
@@ -671,9 +718,6 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
}
}
-// Defined in SPIRVLegalizerInfo.cpp.
-extern bool isTypeFoldingSupported(unsigned Opcode);
-
static void processInstrsWithTypeFolding(MachineFunction &MF,
SPIRVGlobalRegistry *GR,
MachineIRBuilder MIB) {
@@ -788,8 +832,10 @@ insertInlineAsmProcess(MachineFunction &MF, SPIRVGlobalRegistry *GR,
for (unsigned IntrIdx = 3; IntrIdx < I1->getNumOperands(); ++IntrIdx)
AsmCall.addUse(I1->getOperand(IntrIdx).getReg());
}
- for (MachineInstr *MI : ToProcess)
+ for (MachineInstr *MI : ToProcess) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
}
static void insertInlineAsm(MachineFunction &MF, SPIRVGlobalRegistry *GR,
@@ -835,8 +881,10 @@ static void insertSpirvDecorations(MachineFunction &MF, SPIRVGlobalRegistry *GR,
ToErase.push_back(&MI);
}
}
- for (MachineInstr *MI : ToErase)
+ for (MachineInstr *MI : ToErase) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
}
// LLVM allows the switches to use registers as cases, while SPIR-V required
@@ -875,7 +923,8 @@ static void processSwitchesConstants(MachineFunction &MF,
// Some instructions are used during CodeGen but should never be emitted.
// Cleaning up those.
-static void cleanupHelperInstructions(MachineFunction &MF) {
+static void cleanupHelperInstructions(MachineFunction &MF,
+ SPIRVGlobalRegistry *GR) {
SmallVector<MachineInstr *, 8> ToEraseMI;
for (MachineBasicBlock &MBB : MF) {
for (MachineInstr &MI : MBB) {
@@ -885,8 +934,10 @@ static void cleanupHelperInstructions(MachineFunction &MF) {
}
}
- for (MachineInstr *MI : ToEraseMI)
+ for (MachineInstr *MI : ToEraseMI) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
}
// Find all usages of G_BLOCK_ADDR in our intrinsics and replace those
@@ -988,6 +1039,7 @@ static void processBlockAddr(MachineFunction &MF, SPIRVGlobalRegistry *GR,
ConstantExpr::getIntToPtr(Replacement, BA->getType()));
BA->destroyConstant();
}
+ GR->invalidateMachineInstr(BlockAddrI);
BlockAddrI->eraseFromParent();
}
}
@@ -1036,13 +1088,13 @@ bool SPIRVPreLegalizer::runOnMachineFunction(MachineFunction &MF) {
DenseMap<MachineInstr *, Type *> TargetExtConstTypes;
// to keep record of tracked constants
addConstantsToTrack(MF, GR, ST, TargetExtConstTypes);
- foldConstantsIntoIntrinsics(MF, MIB);
+ foldConstantsIntoIntrinsics(MF, GR, MIB);
insertBitcasts(MF, GR, MIB);
generateAssignInstrs(MF, GR, MIB, TargetExtConstTypes);
processSwitchesConstants(MF, GR, MIB);
processBlockAddr(MF, GR, MIB);
- cleanupHelperInstructions(MF);
+ cleanupHelperInstructions(MF, GR);
processInstrsWithTypeFolding(MF, GR, MIB);
removeImplicitFallthroughs(MF, MIB);
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp
index 269524b2410c2..71f08aedd7777 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp
@@ -96,16 +96,21 @@ void applySPIRVDistance(MachineInstr &MI, MachineRegisterInfo &MRI,
.addUse(SubOperand1) // Operand X
.addUse(SubOperand2); // Operand Y
+ SPIRVGlobalRegistry *GR =
+ MI.getMF()->getSubtarget<SPIRVSubtarget>().getSPIRVGlobalRegistry();
auto RemoveAllUses = [&](Register Reg) {
SmallVector<MachineInstr *, 4> UsesToErase;
for (auto &UseMI : MRI.use_instructions(Reg))
UsesToErase.push_back(&UseMI);
// calling eraseFromParent to early invalidates the iterator.
- for (auto *MIToErase : UsesToErase)
+ for (auto *MIToErase : UsesToErase) {
+ GR->invalidateMachineInstr(MIToErase);
MIToErase->eraseFromParent();
+ }
};
RemoveAllUses(SubDestReg); // remove all uses of FSUB Result
+ GR->invalidateMachineInstr(SubInstr);
SubInstr->eraseFromParent(); // remove FSUB instruction
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index 8380cd579004d..6e6125c7bd66d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -186,7 +186,8 @@ MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I) {
if (Opcode == SPIRV::OpFunction || Opcode == SPIRV::OpFunctionParameter) {
IsHeader = true;
} else if (IsHeader &&
- !(Opcode == SPIRV::ASSIGN_TYPE || Opcode == SPIRV::OpLabel)) {
+ !(Opcode == SPIRV::ASSIGN_TYPE || Opcode == SPIRV::TYPEREF ||
+ Opcode == SPIRV::OpLabel)) {
++It;
break;
}
@@ -303,20 +304,7 @@ SPIRV::Scope::Scope getMemScope(LLVMContext &Ctx, SyncScope::ID Id) {
return SPIRV::Scope::Device;
return SPIRV::Scope::CrossDevice;
}
-/*
-MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
- const MachineRegisterInfo *MRI) {
- MachineInstr *MI = MRI->getVRegDef(ConstReg);
- //if (MI->getOpcode() == SPIRV::G_TRUNC || MI->getOpcode() == SPIRV::G_ZEXT)
- // return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
- if (MI->getOpcode() == SPIRV::ASSIGN_TYPE)
- return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
- if (auto *GI = dyn_cast<GIntrinsic>(MI))
- if (GI->is(Intrinsic::spv_track_constant))
- return MRI->getVRegDef(ConstReg = MI->getOperand(2).getReg());
- return MI;
-}
-*/
+
MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
const MachineRegisterInfo *MRI) {
MachineInstr *MI = MRI->getVRegDef(ConstReg);
@@ -860,4 +848,82 @@ void createContinuedInstructions(MachineIRBuilder &MIRBuilder, unsigned Opcode,
}
}
+const std::set<unsigned> &getTypeFoldingSupportedOpcodes() {
+ // clang-format off
+ static const std::set<unsigned> TypeFoldingSupportingOpcs = {
+ TargetOpcode::G_ADD,
+ TargetOpcode::G_FADD,
+ TargetOpcode::G_STRICT_FADD,
+ TargetOpcode::G_SUB,
+ TargetOpcode::G_FSUB,
+ TargetOpcode::G_STRICT_FSUB,
+ TargetOpcode::G_MUL,
+ TargetOpcode::G_FMUL,
+ TargetOpcode::G_STRICT_FMUL,
+ TargetOpcode::G_SDIV,
+ TargetOpcode::G_UDIV,
+ TargetOpcode::G_FDIV,
+ TargetOpcode::G_STRICT_FDIV,
+ TargetOpcode::G_SREM,
+ TargetOpcode::G_UREM,
+ TargetOpcode::G_FREM,
+ TargetOpcode::G_STRICT_FREM,
+ TargetOpcode::G_FNEG,
+ TargetOpcode::G_CONSTANT,
+ TargetOpcode::G_FCONSTANT,
+ TargetOpcode::G_AND,
+ TargetOpcode::G_OR,
+ TargetOpcode::G_XOR,
+ TargetOpcode::G_SHL,
+ TargetOpcode::G_ASHR,
+ TargetOpcode::G_LSHR,
+ TargetOpcode::G_SELECT,
+ TargetOpcode::G_EXTRACT_VECTOR_ELT,
+ };
+ // clang-format on
+ return TypeFoldingSupportingOpcs;
+}
+
+bool isTypeFoldingSupported(unsigned Opcode) {
+ return getTypeFoldingSupportedOpcodes().count(Opcode) > 0;
+}
+
+// Traversing [g]MIR accounting for pseudo-instructions.
+MachineInstr *passCopy(MachineInstr *Def, const MachineRegisterInfo *MRI) {
+ return (Def->getOpcode() == SPIRV::ASSIGN_TYPE ||
+ Def->getOpcode() == TargetOpcode::COPY)
+ ? MRI->getVRegDef(Def->getOperand(1).getReg())
+ : Def;
+}
+
+MachineInstr *getDef(const MachineOperand &MO, const MachineRegisterInfo *MRI) {
+ if (MachineInstr *Def = MRI->getVRegDef(MO.getReg()))
+ return passCopy(Def, MRI);
+ return nullptr;
+}
+
+MachineInstr *getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI) {
+ if (MachineInstr *Def = getDef(MO, MRI)) {
+ if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
+ Def->getOpcode() == SPIRV::OpConstantI)
+ return Def;
+ }
+ return nullptr;
+}
+
+int64_t foldImm(const MachineOperand &MO, const MachineRegisterInfo *MRI) {
+ if (MachineInstr *Def = getImm(MO, MRI)) {
+ if (Def->getOpcode() == SPIRV::OpConstantI)
+ return Def->getOperand(2).getImm();
+ if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
+ return Def->getOperand(1).getCImm()->getZExtValue();
+ }
+ llvm_unreachable("Unexpected integer constant pattern");
+}
+
+unsigned getArrayComponentCount(const MachineRegisterInfo *MRI,
+ const MachineInstr *ResType) {
+ return foldImm(ResType->getOperand(2), MRI);
+}
+
} // namespace llvm
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.h b/llvm/lib/Target/SPIRV/SPIRVUtils.h
index 180d3a29d170f..a0b8ba18fc7ba 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.h
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.h
@@ -459,5 +459,17 @@ void createContinuedInstructions(MachineIRBuilder &MIRBuilder, unsigned Opcode,
ArrayRef<Register> Args,
Register ReturnRegister, Register TypeID);
+// Instruction selection directed by type folding.
+const std::set<unsigned> &getTypeFoldingSupportedOpcodes();
+bool isTypeFoldingSupported(unsigned Opcode);
+
+// Traversing [g]MIR accounting for pseudo-instructions.
+MachineInstr *passCopy(MachineInstr *Def, const MachineRegisterInfo *MRI);
+MachineInstr *getDef(const MachineOperand &MO, const MachineRegisterInfo *MRI);
+MachineInstr *getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI);
+int64_t foldImm(const MachineOperand &MO, const MachineRegisterInfo *MRI);
+unsigned getArrayComponentCount(const MachineRegisterInfo *MRI,
+ const MachineInstr *ResType);
+
} // namespace llvm
#endif // LLVM_LIB_TARGET_SPIRV_SPIRVUTILS_H
diff --git a/llvm/test/CodeGen/SPIRV/atomicrmw.ll b/llvm/test/CodeGen/SPIRV/atomicrmw.ll
index 07576056117cb..a6cfe56cd06c3 100644
--- a/llvm/test/CodeGen/SPIRV/atomicrmw.ll
+++ b/llvm/test/CodeGen/SPIRV/atomicrmw.ll
@@ -4,8 +4,8 @@
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-; CHECK: %[[#Int:]] = OpTypeInt 32 0
-; CHECK-DAG: %[[#Scope_CrossDevice:]] = OpConstant %[[#Int]] 0{{$}}
+; CHECK-DAG: %[[#Int:]] = OpTypeInt 32 0
+; CHECK-DAG: %[[#Scope_CrossDevice:]] = OpConstantNull %[[#Int]]
; CHECK-DAG: %[[#MemSem_Acquire:]] = OpConstant %[[#Int]] 2
; CHECK-DAG: %[[#MemSem_Release:]] = OpConstant %[[#Int]] 4{{$}}
; CHECK-DAG: %[[#MemSem_AcquireRelease:]] = OpConstant %[[#Int]] 8
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll
index 93ea49afc6589..2b29b4fca5671 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll
@@ -6,23 +6,23 @@
; CHECK-MIR-DAG: [[i32type:%[0-9]+\:type]] = OpTypeInt 32, 0
; CHECK-MIR-DAG: [[void_type:%[0-9]+\:type\(s64\)]] = OpTypeVoid
-; CHECK-MIR-DAG: [[i32_8:%[0-9]+\:iid]] = OpConstantI [[i32type]], 8
-; CHECK-MIR-DAG: [[i32_0:%[0-9]+\:iid]] = OpConstantI [[i32type]], 0
-; CHECK-MIR-DAG: [[i32_5:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 5
-; CHECK-MIR-DAG: [[enc_float:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 3
-; CHECK-MIR-DAG: [[enc_boolean:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 2
+; CHECK-MIR-DAG: [[i32_8:%[0-9]+\:iid]] = OpConstantI [[i32type]], 8{{$}}
+; CHECK-MIR-DAG: [[i32_0:%[0-9]+\:pid]] = OpConstantNull
+; CHECK-MIR-DAG: [[i32_5:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 5{{$}}
+; CHECK-MIR-DAG: [[enc_float:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 3{{$}}
+; CHECK-MIR-DAG: [[enc_boolean:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 2{{$}}
; CHECK-MIR-DAG: [[bool:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_8]], [[enc_boolean]], [[i32_0]]
-; CHECK-MIR-DAG: [[i32_16:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 16
-; CHECK-MIR-DAG: [[enc_signed:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 4
+; CHECK-MIR-DAG: [[i32_16:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 16{{$}}
+; CHECK-MIR-DAG: [[enc_signed:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 4{{$}}
; CHECK-MIR-DAG: [[short:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_16]], [[enc_signed]], [[i32_0]]
; CHECK-MIR-DAG: [[char:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_8]], [[i32_5]], [[i32_0]]
-; CHECK-MIR-DAG: [[i32_64:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 64
+; CHECK-MIR-DAG: [[i32_64:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 64{{$}}
; CHECK-MIR-DAG: [[long:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_64]], [[enc_signed]], [[i32_0]]
-; CHECK-MIR-DAG: [[i32_32:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 32
-; CHECK-MIR-DAG: [[enc_unsigned:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 6
+; CHECK-MIR-DAG: [[i32_32:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 32{{$}}
+; CHECK-MIR-DAG: [[enc_unsigned:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 6{{$}}
; CHECK-MIR-DAG: [[unsigned_int:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_32]], [[enc_unsigned]], [[i32_0]]
; CHECK-MIR-DAG: [[unsigned_short:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_16]], [[enc_unsigned]], [[i32_0]]
-; CHECK-MIR-DAG: [[enc_unsigned_char:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 7
+; CHECK-MIR-DAG: [[enc_unsigned_char:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 7{{$}}
; CHECK-MIR-DAG: [[unsigned_char:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_8]], [[enc_unsigned_char]], [[i32_0]]
; CHECK-MIR-DAG: [[unsigned_long:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_64]], [[enc_unsigned]], [[i32_0]]
; CHECK-MIR-DAG: [[float:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_32]], [[enc_float]], [[i32_0]]
@@ -43,17 +43,17 @@
; CHECK-MIR-DAG: OpExtInst [[void_type]], 3, 3, [[debug_info_none]], [[i32_5]], [[i32_0]]
; CHECK-SPIRV: [[i32type:%[0-9]+]] = OpTypeInt 32 0
-; CHECK-SPIRV-DAG: [[i32_8:%[0-9]+]] = OpConstant [[i32type]] 8
-; CHECK-SPIRV-DAG: [[i32_0:%[0-9]+]] = OpConstant [[i32type]] 0
-; CHECK-SPIRV-DAG: [[i32_5:%[0-9]+]] = OpConstant [[i32type]] 5
-; CHECK-SPIRV-DAG: [[enc_float:%[0-9]+]] = OpConstant [[i32type]] 3
-; CHECK-SPIRV-DAG: [[enc_boolean:%[0-9]+]] = OpConstant [[i32type]] 2
-; CHECK-SPIRV-DAG: [[i32_16:%[0-9]+]] = OpConstant [[i32type]] 16
-; CHECK-SPIRV-DAG: [[enc_signed:%[0-9]+]] = OpConstant [[i32type]] 4
-; CHECK-SPIRV-DAG: [[i32_64:%[0-9]+]] = OpConstant [[i32type]] 64
-; CHECK-SPIRV-DAG: [[i32_32:%[0-9]+]] = OpConstant [[i32type]] 32
-; CHECK-SPIRV-DAG: [[enc_unsigned:%[0-9]+]] = OpConstant [[i32type]] 6
-; CHECK-SPIRV-DAG: [[enc_unsigned_char:%[0-9]+]] = OpConstant [[i32type]] 7
+; CHECK-SPIRV-DAG: [[i32_8:%[0-9]+]] = OpConstant [[i32type]] 8{{$}}
+; CHECK-SPIRV-DAG: [[i32_0:%[0-9]+]] = OpConstant [[i32type]] 0{{$}}
+; CHECK-SPIRV-DAG: [[i32_5:%[0-9]+]] = OpConstant [[i32type]] 5{{$}}
+; CHECK-SPIRV-DAG: [[enc_float:%[0-9]+]] = OpConstant [[i32type]] 3{{$}}
+; CHECK-SPIRV-DAG: [[enc_boolean:%[0-9]+]] = OpConstant [[i32type]] 2{{$}}
+; CHECK-SPIRV-DAG: [[i32_16:%[0-9]+]] = OpConstant [[i32type]] 16{{$}}
+; CHECK-SPIRV-DAG: [[enc_signed:%[0-9]+]] = OpConstant [[i32type]] 4{{$}}
+; CHECK-SPIRV-DAG: [[i32_64:%[0-9]+]] = OpConstant [[i32type]] 64{{$}}
+; CHECK-SPIRV-DAG: [[i32_32:%[0-9]+]] = OpConstant [[i32type]] 32{{$}}
+; CHECK-SPIRV-DAG: [[enc_unsigned:%[0-9]+]] = OpConstant [[i32type]] 6{{$}}
+; CHECK-SPIRV-DAG: [[enc_unsigned_char:%[0-9]+]] = OpConstant [[i32type]] 7{{$}}
; CHECK-SPIRV-DAG: [[bool:%[0-9]+]] = OpExtInst {{%[0-9]+ %[0-9]+}} DebugTypeBasic {{%[0-9]+}} [[i32_8]] [[enc_boolean]] [[i32_0]]
; CHECK-SPIRV-DAG: [[short:%[0-9]+]] = OpExtInst {{%[0-9]+ %[0-9]+}} DebugTypeBasic {{%[0-9]+}} [[i32_16]] [[enc_signed]] [[i32_0]]
; CHECK-SPIRV-DAG: [[char:%[0-9]+]] = OpExtInst {{%[0-9]+ %[0-9]+}} DebugTypeBasic {{%[0-9]+}} [[i32_8]] [[i32_5]] [[i32_0]]
diff --git a/llvm/test/CodeGen/SPIRV/freeze.ll b/llvm/test/CodeGen/SPIRV/freeze.ll
index fe4335722fe8b..9077d2ede72a9 100644
--- a/llvm/test/CodeGen/SPIRV/freeze.ll
+++ b/llvm/test/CodeGen/SPIRV/freeze.ll
@@ -14,15 +14,12 @@
; CHECK-DAG: %[[FloatTy:.*]] = OpTypeFloat 32
; CHECK-DAG: %[[ShortTy:.*]] = OpTypeInt 16 0
; CHECK-DAG: %[[IntTy:.*]] = OpTypeInt 32 0
-; CHECK-DAG: %[[Undef:.*]] = OpUndef %[[ShortTy]]
+; CHECK-DAG: %[[Undef16:.*]] = OpUndef %[[ShortTy]]
+; CHECK-DAG: %[[Undef32:.*]] = OpUndef %[[IntTy]]
+; CHECK-DAG: %[[UndefFloat:.*]] = OpUndef %[[FloatTy]]
; CHECK-DAG: %[[Const100]] = OpConstant %[[IntTy]] 100
-; CHECK-DAG: %[[StaticPoisonIntFreeze]] = OpConstantNull %[[IntTy]]
-; CHECK-DAG: %[[StaticPoisonFloatFreeze]] = OpConstantNull %[[FloatTy]]
; CHECK: %[[Arg1]] = OpFunctionParameter %[[FloatTy]]
-; CHECK: %[[NotAStaticPoison]] = OpIAdd %[[ShortTy]] %[[Arg2]] %[[Undef]]
-
-target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
-target triple = "spir64-unknown-unknown"
+; CHECK: %[[NotAStaticPoison]] = OpIAdd %[[ShortTy]] %[[Arg2]] %[[Undef16]]
define spir_func void @foo(float %arg1, i16 %arg2) {
entry:
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_i8packed.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_i8packed.ll
index 2ac557b43916b..8715fc324c071 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_i8packed.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_i8packed.ll
@@ -11,7 +11,7 @@
; CHECK: %[[#int_32:]] = OpTypeInt 32 0
; CHECK-EXP-DAG: %[[#int_8:]] = OpTypeInt 8 0
-; CHECK-EXP-DAG: %[[#zero:]] = OpConstantNull %[[#int_8]]
+; CHECK-EXP-DAG: %[[#zero:]] = OpConstant %[[#int_8]] 0{{$}}
; CHECK-EXP-DAG: %[[#eight:]] = OpConstant %[[#int_8]] 8
; CHECK-EXP-DAG: %[[#sixteen:]] = OpConstant %[[#int_8]] 16
; CHECK-EXP-DAG: %[[#twentyfour:]] = OpConstant %[[#int_8]] 24
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_u8packed.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_u8packed.ll
index 8acdb7d2ea324..a43d0be9e775b 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_u8packed.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_u8packed.ll
@@ -11,7 +11,7 @@
; CHECK: %[[#int_32:]] = OpTypeInt 32 0
; CHECK-EXP-DAG: %[[#int_8:]] = OpTypeInt 8 0
-; CHECK-EXP-DAG: %[[#zero:]] = OpConstantNull %[[#int_8]]
+; CHECK-EXP-DAG: %[[#zero:]] = OpConstant %[[#int_8]] 0{{$}}
; CHECK-EXP-DAG: %[[#eight:]] = OpConstant %[[#int_8]] 8
; CHECK-EXP-DAG: %[[#sixteen:]] = OpConstant %[[#int_8]] 16
; CHECK-EXP-DAG: %[[#twentyfour:]] = OpConstant %[[#int_8]] 24
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageDynIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageDynIdx.ll
index 94ebe74148b95..6a6d810e6babd 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageDynIdx.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageDynIdx.ll
@@ -1,9 +1,9 @@
; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
-; CHECK: OpCapability Shader
-; CHECK-NEXT: OpCapability StorageImageArrayDynamicIndexing
-; CHECK-NEXT: OpCapability Image1D
+; CHECK-DAG: OpCapability Shader
+; CHECK-DAG: OpCapability StorageImageArrayDynamicIndexing
+; CHECK-DAG: OpCapability Image1D
; CHECK-NOT: OpCapability
; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
@@ -14,7 +14,7 @@
; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
; CHECK-DAG: [[One:%[0-9]+]] = OpConstant [[int]] 1
-; CHECK-DAG: [[Zero:%[0-9]+]] = OpConstant [[int]] 0
+; CHECK-DAG: [[Zero:%[0-9]+]] = OpConstant [[int]] 0{{$}}
; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageNonUniformIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageNonUniformIdx.ll
index f9466e431c19c..16f3724d5d10a 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageNonUniformIdx.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageNonUniformIdx.ll
@@ -1,10 +1,10 @@
; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
-; CHECK: OpCapability Shader
-; CHECK: OpCapability ShaderNonUniformEXT
-; CHECK-NEXT: OpCapability StorageImageArrayNonUniformIndexing
-; CHECK-NEXT: OpCapability Image1D
+; CHECK-DAG: OpCapability Shader
+; CHECK-DAG: OpCapability ShaderNonUniformEXT
+; CHECK-DAG: OpCapability StorageImageArrayNonUniformIndexing
+; CHECK-DAG: OpCapability Image1D
; CHECK-NOT: OpCapability
; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
@@ -21,7 +21,7 @@
; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
; CHECK-DAG: [[One]] = OpConstant [[int]] 1
-; CHECK-DAG: [[Zero]] = OpConstant [[int]] 0
+; CHECK-DAG: [[Zero]] = OpConstant [[int]] 0{{$}}
; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/smul.with.overflow.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/smul.with.overflow.ll
index 2281ccf52bbb4..f839774b4f3e3 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/smul.with.overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/smul.with.overflow.ll
@@ -9,10 +9,12 @@
; CHECK-DAG: %[[PtrChar:.*]] = OpTypePointer Function %[[Char]]
; CHECK-DAG: %[[StructChar:.*]] = OpTypeStruct %[[Char]] %[[Char]]
; CHECK-DAG: %[[ZeroChar:.*]] = OpConstant %[[Char]] 0
+; CHECK-DAG: %[[NullChar:.*]] = OpConstantNull %[[Char]]
; CHECK-DAG: %[[Int:.*]] = OpTypeInt 32 0
; CHECK-DAG: %[[PtrInt:.*]] = OpTypePointer Function %[[Int]]
; CHECK-DAG: %[[StructInt:.*]] = OpTypeStruct %[[Int]] %[[Int]]
; CHECK-DAG: %[[ZeroInt:.*]] = OpConstant %[[Int]] 0
+; CHECK-DAG: %[[NullInt:.*]] = OpConstantNull %[[Int]]
; CHECK-DAG: %[[Bool:.*]] = OpTypeBool
; CHECK-DAG: %[[V2Bool:.*]] = OpTypeVector %[[Bool]] 2
; CHECK-DAG: %[[Long:.*]] = OpTypeInt 64 0
@@ -28,7 +30,7 @@
; CHECK: %[[Struct:.*]] = OpSMulExtended %[[StructChar]] %[[A]] %[[B]]
; CHECK: %[[Val:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 0
; CHECK: %[[Over:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 1
-; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[ZeroChar]]
+; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[NullChar]]
; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[ZeroChar]] %[[Val]]
; CHECK: OpStore %[[Ptr]] %[[Res]] Aligned 1
; CHECK: OpReturn
@@ -49,7 +51,7 @@ entry:
; CHECK: %[[Struct2:.*]] = OpSMulExtended %[[StructInt]] %[[B2]] %[[A2]]
; CHECK: %[[Val2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 0
; CHECK: %[[Over2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 1
-; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[ZeroInt]]
+; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[NullInt]]
; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[ZeroInt]] %[[Val2]]
; CHECK: OpStore %[[Ptr2]] %[[Res2]] Aligned 4
; CHECK: OpReturn
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll
index 1c77800a1630d..fc3e9b6ab3f89 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll
@@ -9,10 +9,12 @@
; CHECK-DAG: %[[PtrChar:.*]] = OpTypePointer Function %[[Char]]
; CHECK-DAG: %[[StructChar:.*]] = OpTypeStruct %[[Char]] %[[Char]]
; CHECK-DAG: %[[ZeroChar:.*]] = OpConstant %[[Char]] 0
+; CHECK-DAG: %[[NullChar:.*]] = OpConstantNull %[[Char]]
; CHECK-DAG: %[[Int:.*]] = OpTypeInt 32 0
; CHECK-DAG: %[[PtrInt:.*]] = OpTypePointer Function %[[Int]]
; CHECK-DAG: %[[StructInt:.*]] = OpTypeStruct %[[Int]] %[[Int]]
; CHECK-DAG: %[[ZeroInt:.*]] = OpConstant %[[Int]] 0
+; CHECK-DAG: %[[NullInt:.*]] = OpConstantNull %[[Int]]
; CHECK-DAG: %[[Bool:.*]] = OpTypeBool
; CHECK-DAG: %[[V2Bool:.*]] = OpTypeVector %[[Bool]] 2
; CHECK-DAG: %[[Long:.*]] = OpTypeInt 64 0
@@ -29,7 +31,7 @@
; CHECK: %[[Struct:.*]] = OpIAddCarry %[[StructChar]] %[[A]] %[[B]]
; CHECK: %[[Val:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 0
; CHECK: %[[Over:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 1
-; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[ZeroChar]]
+; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[NullChar]]
; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[ZeroChar]] %[[Val]]
; CHECK: OpStore %[[Ptr]] %[[Res]] Aligned 1
; CHECK: OpReturn
@@ -50,7 +52,7 @@ entry:
; CHECK: %[[Struct2:.*]] = OpIAddCarry %[[StructInt]] %[[B2]] %[[A2]]
; CHECK: %[[Val2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 0
; CHECK: %[[Over2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 1
-; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[ZeroInt]]
+; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[NullInt]]
; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[ZeroInt]] %[[Val2]]
; CHECK: OpStore %[[Ptr2]] %[[Res2]] Aligned 4
; CHECK: OpReturn
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/umul.with.overflow.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/umul.with.overflow.ll
index 7113dd692f6ac..e01489d6995f7 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/umul.with.overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/umul.with.overflow.ll
@@ -9,10 +9,12 @@
; CHECK-DAG: %[[PtrChar:.*]] = OpTypePointer Function %[[Char]]
; CHECK-DAG: %[[StructChar:.*]] = OpTypeStruct %[[Char]] %[[Char]]
; CHECK-DAG: %[[ZeroChar:.*]] = OpConstant %[[Char]] 0
+; CHECK-DAG: %[[NullChar:.*]] = OpConstantNull %[[Char]]
; CHECK-DAG: %[[Int:.*]] = OpTypeInt 32 0
; CHECK-DAG: %[[PtrInt:.*]] = OpTypePointer Function %[[Int]]
; CHECK-DAG: %[[StructInt:.*]] = OpTypeStruct %[[Int]] %[[Int]]
; CHECK-DAG: %[[ZeroInt:.*]] = OpConstant %[[Int]] 0
+; CHECK-DAG: %[[NullInt:.*]] = OpConstantNull %[[Int]]
; CHECK-DAG: %[[Bool:.*]] = OpTypeBool
; CHECK-DAG: %[[V2Bool:.*]] = OpTypeVector %[[Bool]] 2
; CHECK-DAG: %[[Long:.*]] = OpTypeInt 64 0
@@ -28,7 +30,7 @@
; CHECK: %[[Struct:.*]] = OpUMulExtended %[[StructChar]] %[[A]] %[[B]]
; CHECK: %[[Val:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 0
; CHECK: %[[Over:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 1
-; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[ZeroChar]]
+; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[NullChar]]
; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[ZeroChar]] %[[Val]]
; CHECK: OpStore %[[Ptr]] %[[Res]] Aligned 1
; CHECK: OpReturn
@@ -49,7 +51,7 @@ entry:
; CHECK: %[[Struct2:.*]] = OpUMulExtended %[[StructInt]] %[[B2]] %[[A2]]
; CHECK: %[[Val2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 0
; CHECK: %[[Over2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 1
-; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[ZeroInt]]
+; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[NullInt]]
; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[ZeroInt]] %[[Val2]]
; CHECK: OpStore %[[Ptr2]] %[[Res2]] Aligned 4
; CHECK: OpReturn
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/usub.with.overflow.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/usub.with.overflow.ll
index 963dd70f606b6..f7ea655e6529a 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/usub.with.overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/usub.with.overflow.ll
@@ -9,10 +9,12 @@
; CHECK-DAG: %[[PtrChar:.*]] = OpTypePointer Function %[[Char]]
; CHECK-DAG: %[[StructChar:.*]] = OpTypeStruct %[[Char]] %[[Char]]
; CHECK-DAG: %[[ZeroChar:.*]] = OpConstant %[[Char]] 0
+; CHECK-DAG: %[[NullChar:.*]] = OpConstantNull %[[Char]]
; CHECK-DAG: %[[Int:.*]] = OpTypeInt 32 0
; CHECK-DAG: %[[PtrInt:.*]] = OpTypePointer Function %[[Int]]
; CHECK-DAG: %[[StructInt:.*]] = OpTypeStruct %[[Int]] %[[Int]]
; CHECK-DAG: %[[ZeroInt:.*]] = OpConstant %[[Int]] 0
+; CHECK-DAG: %[[NullInt:.*]] = OpConstantNull %[[Int]]
; CHECK-DAG: %[[Bool:.*]] = OpTypeBool
; CHECK-DAG: %[[V2Bool:.*]] = OpTypeVector %[[Bool]] 2
; CHECK-DAG: %[[Long:.*]] = OpTypeInt 64 0
@@ -28,7 +30,7 @@
; CHECK: %[[Struct:.*]] = OpISubBorrow %[[StructChar]] %[[A]] %[[B]]
; CHECK: %[[Val:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 0
; CHECK: %[[Over:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 1
-; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[ZeroChar]]
+; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[NullChar]]
; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[ZeroChar]] %[[Val]]
; CHECK: OpStore %[[Ptr]] %[[Res]] Aligned 1
; CHECK: OpReturn
@@ -49,7 +51,7 @@ entry:
; CHECK: %[[Struct2:.*]] = OpISubBorrow %[[StructInt]] %[[B2]] %[[A2]]
; CHECK: %[[Val2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 0
; CHECK: %[[Over2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 1
-; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[ZeroInt]]
+; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[NullInt]]
; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[ZeroInt]] %[[Val2]]
; CHECK: OpStore %[[Ptr2]] %[[Res2]] Aligned 4
; CHECK: OpReturn
>From a9cd2191767d844c7e87a5998b0e23d7a249b9bb Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Fri, 14 Mar 2025 10:41:27 -0700
Subject: [PATCH 09/12] experiment with cashes
---
llvm/lib/Target/SPIRV/SPIRVIRMapping.h | 67 +++++++++++++------
llvm/lib/Target/SPIRV/SPIRVInstrInfo.td | 3 -
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 56 +++++-----------
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 13 ++--
llvm/lib/Target/SPIRV/SPIRVUtils.cpp | 3 +-
5 files changed, 65 insertions(+), 77 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
index bec2a989483e8..feee13c0b3117 100644
--- a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
+++ b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
@@ -26,7 +26,7 @@
namespace llvm {
namespace SPIRV {
-
+/*
inline size_t to_hash(const MachineInstr *MI,
std::unordered_set<const MachineInstr *> &Visited) {
if (!MI || !Visited.insert(MI).second)
@@ -47,6 +47,21 @@ inline size_t to_hash(const MachineInstr *MI) {
std::unordered_set<const MachineInstr *> Visited;
return to_hash(MI, Visited);
}
+*/
+
+inline size_t to_hash(const MachineInstr *MI) {
+ hash_code H = llvm::hash_combine(MI->getOpcode(), MI->getNumOperands());
+ for (unsigned I = MI->getNumDefs(); I < MI->getNumOperands(); ++I) {
+ const MachineOperand &MO = MI->getOperand(I);
+ if (MO.getType() == MachineOperand::MO_CImmediate)
+ H = llvm::hash_combine(H, MO.getType(), MO.getCImm());
+ else if (MO.getType() == MachineOperand::MO_FPImmediate)
+ H = llvm::hash_combine(H, MO.getType(), MO.getFPImm());
+ else
+ H = llvm::hash_combine(H, MO.getType());
+ }
+ return H;
+}
using MIHandle = std::pair<const MachineInstr *, size_t>;
@@ -169,46 +184,54 @@ inline IRHandle handle(const MachineInstr *KeyMI) {
// per an LLVM/GlobalISel entity (e.g., Type, Constant, Machine Instruction).
class SPIRVIRMapping {
DenseMap<SPIRV::IRHandleMF, SPIRV::MIHandle> Vregs;
- DenseMap<SPIRV::MIHandle, SPIRV::IRHandle> Defs;
+ DenseMap<const MachineInstr *, SPIRV::IRHandleMF> Defs;
public:
bool add(SPIRV::IRHandle Handle, const MachineInstr *MI) {
- if (std::get<1>(Handle) == 17 && std::get<2>(Handle) == 8) {
- const Value *Ptr = (const Value *)std::get<0>(Handle);
- if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Ptr)) {
- if (CI->getZExtValue() == 8 || CI->getZExtValue() == 5) {
- [[maybe_unused]] uint64_t v = CI->getZExtValue();
- }
- }
+ if (auto DefIt = Defs.find(MI); DefIt != Defs.end()) {
+ auto [ExistHandle, ExistMF] = DefIt->second;
+ if (Handle == ExistHandle && MI->getMF() == ExistMF)
+ return false; // already exists
+ // invalidate the record
+ Vregs.erase(DefIt->second);
+ Defs.erase(DefIt);
}
- auto MIKey = SPIRV::getMIKey(MI);
- auto [It, Inserted] =
- Vregs.try_emplace(std::make_pair(Handle, MI->getMF()), MIKey);
- if (Inserted) {
- [[maybe_unused]] auto [_, IsConsistent] =
- Defs.insert_or_assign(MIKey, Handle);
- assert(IsConsistent);
+ SPIRV::IRHandleMF HandleMF = SPIRV::getIRHandleMF(Handle, MI->getMF());
+ SPIRV::MIHandle MIKey = SPIRV::getMIKey(MI);
+ auto It1 = Vregs.try_emplace(HandleMF, MIKey);
+ if (!It1.second) {
+ // there is an expired record
+ auto [ExistMI, _] = It1.first->second;
+ // invalidate the record
+ Defs.erase(ExistMI);
+ // update the record
+ It1.first->second = MIKey;
}
- return Inserted;
+ [[maybe_unused]] auto It2 = Defs.try_emplace(MI, HandleMF);
+ assert(It2.second);
+ return true;
}
bool erase(const MachineInstr *MI) {
bool Res = false;
- if (auto It = Defs.find(SPIRV::getMIKey(MI)); It != Defs.end()) {
- Res = Vregs.erase(SPIRV::getIRHandleMF(It->second, MI->getMF()));
+ if (auto It = Defs.find(MI); It != Defs.end()) {
+ Res = Vregs.erase(It->second);
Defs.erase(It);
}
return Res;
}
const MachineInstr *findMI(SPIRV::IRHandle Handle,
const MachineFunction *MF) {
- auto It = Vregs.find(SPIRV::getIRHandleMF(Handle, MF));
+ SPIRV::IRHandleMF HandleMF = SPIRV::getIRHandleMF(Handle, MF);
+ auto It = Vregs.find(HandleMF);
if (It == Vregs.end())
return nullptr;
auto [MI, Hash] = It->second;
- if (SPIRV::to_hash(MI) != Hash) {
+ assert(SPIRV::to_hash(MI) == Hash);
+ assert(Defs.find(MI) != Defs.end() && Defs.find(MI)->second == HandleMF);
+ /*if (SPIRV::to_hash(MI) != Hash) {
erase(MI);
return nullptr;
- }
+ }*/
return MI;
}
Register find(SPIRV::IRHandle Handle, const MachineFunction *MF) {
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
index 4b9bddd661f63..3499c2340a2dd 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
@@ -15,7 +15,6 @@ include "SPIRVSymbolicOperands.td"
// Codegen only metadata instructions
let isCodeGenOnly=1 in {
- def TYPEREF: Pseudo<(outs), (ins ID:$src_id, TYPE:$src_ty)>;
def ASSIGN_TYPE: Pseudo<(outs ID:$dst_id), (ins ID:$src_id, TYPE:$src_ty)>;
def DECL_TYPE: Pseudo<(outs ID:$dst_id), (ins ID:$src_id, TYPE:$src_ty)>;
def GET_ID: Pseudo<(outs iID:$dst_id), (ins iID:$src)>;
@@ -29,10 +28,8 @@ let isCodeGenOnly=1 in {
def SPVTypeBin : SDTypeProfile<1, 2, []>;
def assigntype : SDNode<"SPIRVISD::AssignType", SPVTypeBin>;
-def typeref : SDNode<"SPIRVISD::TypeRef", SPVTypeBin>;
def : GINodeEquiv<ASSIGN_TYPE, assigntype>;
-def : GINodeEquiv<TYPEREF, typeref>;
class BinOp<string name, bits<16> opCode, list<dag> pattern=[]>
: Op<opCode, (outs ID:$dst), (ins TYPE:$src_ty, ID:$src, ID:$src2),
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 8f1ac07dd9450..64d9a291f637d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -393,26 +393,21 @@ void SPIRVInstructionSelector::resetVRegsType(MachineFunction &MF) {
}
for (const auto &MBB : MF) {
for (const auto &MI : MBB) {
- if (MI.getOpcode() == SPIRV::ASSIGN_TYPE) {
- Register DstReg = MI.getOperand(0).getReg();
- LLT DstType = MRI.getType(DstReg);
- Register SrcReg = MI.getOperand(1).getReg();
- LLT SrcType = MRI.getType(SrcReg);
- if (DstType != SrcType)
- MRI.setType(DstReg, MRI.getType(SrcReg));
-
- const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(DstReg);
- const TargetRegisterClass *SrcRC = MRI.getRegClassOrNull(SrcReg);
- if (DstRC != SrcRC && SrcRC)
- MRI.setRegClass(DstReg, SrcRC);
- } else if (MI.getOpcode() == SPIRV::TYPEREF) {
- Register DstReg = MI.getOperand(0).getReg();
- LLT DstType = MRI.getType(DstReg);
- Register SrcReg = MI.getOperand(1).getReg();
- LLT SrcType = MRI.getType(SrcReg);
- if (DstType != SrcType)
- MRI.setType(DstReg, MRI.getType(SrcReg));
- }
+ //GR.invalidateMachineInstr(&I);
+ if (MI.getOpcode() != SPIRV::ASSIGN_TYPE)
+ continue;
+
+ Register DstReg = MI.getOperand(0).getReg();
+ LLT DstType = MRI.getType(DstReg);
+ Register SrcReg = MI.getOperand(1).getReg();
+ LLT SrcType = MRI.getType(SrcReg);
+ if (DstType != SrcType)
+ MRI.setType(DstReg, MRI.getType(SrcReg));
+
+ const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(DstReg);
+ const TargetRegisterClass *SrcRC = MRI.getRegClassOrNull(SrcReg);
+ if (DstRC != SrcRC && SrcRC)
+ MRI.setRegClass(DstReg, SrcRC);
}
}
}
@@ -523,27 +518,6 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
GR.invalidateMachineInstr(&I);
I.removeFromParent();
return true;
- } else if (Opcode == SPIRV::TYPEREF) {
- Register SrcReg = I.getOperand(0).getReg();
- auto *Def = MRI->getVRegDef(SrcReg);
- if (isTypeFoldingSupported(Def->getOpcode())) {
- bool Res = selectImpl(I, *CoverageInfo);
- LLVM_DEBUG({
- if (!Res && Def->getOpcode() != TargetOpcode::G_CONSTANT) {
- dbgs() << "Unexpected pattern in ASSIGN_TYPE.\nInstruction: ";
- I.print(dbgs());
- }
- });
- assert(Res || Def->getOpcode() == TargetOpcode::G_CONSTANT);
- if (Res) {
- if (!isTriviallyDead(*Def, *MRI) && isDead(*Def, *MRI))
- DeadMIs.insert(Def);
- return Res;
- }
- }
- GR.invalidateMachineInstr(&I);
- I.removeFromParent();
- return true;
} else if (I.getNumDefs() == 1) {
// Make all vregs 64 bits (for SPIR-V IDs).
MRI->setType(I.getOperand(0).getReg(), LLT::scalar(64));
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 0ece31ee88abe..aea49c6a618cd 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -564,8 +564,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
assert(Def && "Expecting an instruction that defines the register");
// G_GLOBAL_VALUE already has type info.
if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
- Def->getOpcode() != SPIRV::ASSIGN_TYPE &&
- Def->getOpcode() != SPIRV::TYPEREF)
+ Def->getOpcode() != SPIRV::ASSIGN_TYPE)
insertAssignInstr(Reg, nullptr, AssignedPtrType, GR, MIB,
MF.getRegInfo());
ToErase.push_back(&MI);
@@ -576,8 +575,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
assert(Def && "Expecting an instruction that defines the register");
// G_GLOBAL_VALUE already has type info.
if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
- Def->getOpcode() != SPIRV::ASSIGN_TYPE &&
- Def->getOpcode() != SPIRV::TYPEREF)
+ Def->getOpcode() != SPIRV::ASSIGN_TYPE)
insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MF.getRegInfo());
ToErase.push_back(&MI);
} else if (MIOp == TargetOpcode::FAKE_USE && MI.getNumOperands() > 0) {
@@ -614,8 +612,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
if (isSpvIntrinsic(UseMI, Intrinsic::spv_assign_type) ||
isSpvIntrinsic(UseMI, Intrinsic::spv_assign_name))
continue;
- if (UseMI.getOpcode() == SPIRV::ASSIGN_TYPE ||
- UseMI.getOpcode() == SPIRV::TYPEREF)
+ if (UseMI.getOpcode() == SPIRV::ASSIGN_TYPE)
NeedAssignType = false;
}
Type *Ty = nullptr;
@@ -665,9 +662,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
if (!ElemTy) {
// There may be a case when we already know Reg's type.
MachineInstr *NextMI = MI.getNextNode();
- if (!NextMI ||
- (NextMI->getOpcode() != SPIRV::ASSIGN_TYPE &&
- NextMI->getOpcode() != SPIRV::TYPEREF) ||
+ if (!NextMI || NextMI->getOpcode() != SPIRV::ASSIGN_TYPE ||
NextMI->getOperand(1).getReg() != Reg)
llvm_unreachable("Unexpected opcode");
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index 6e6125c7bd66d..b101e562051a4 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -186,8 +186,7 @@ MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I) {
if (Opcode == SPIRV::OpFunction || Opcode == SPIRV::OpFunctionParameter) {
IsHeader = true;
} else if (IsHeader &&
- !(Opcode == SPIRV::ASSIGN_TYPE || Opcode == SPIRV::TYPEREF ||
- Opcode == SPIRV::OpLabel)) {
+ !(Opcode == SPIRV::ASSIGN_TYPE || Opcode == SPIRV::OpLabel)) {
++It;
break;
}
>From 44c6c7c87d364f8758d5f7467732452056ba61b8 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 17 Mar 2025 07:31:56 -0700
Subject: [PATCH 10/12] instruction selection for constants to account for
duplicate tracking
---
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 13 +-
llvm/lib/Target/SPIRV/SPIRVInstrInfo.td | 43 +-
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 73 ++--
llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 5 +-
llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp | 27 +-
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 9 +-
.../CodeGen/SPIRV/AtomicCompareExchange.ll | 15 +-
.../SPIRV/GroupAndSubgroupInstructions.spvasm | 374 ++++++++++++++++++
.../CodeGen/SPIRV/const-array-in-struct.ll | 19 +-
llvm/test/CodeGen/SPIRV/const-composite.ll | 10 +-
.../SPIRV/debug-info/debug-type-basic.ll | 22 +-
.../SPIRV/debug-info/debug-type-pointer.ll | 4 +-
.../atomicrmw_faddfsub_double.ll | 8 +-
.../atomicrmw_faddfsub_float.ll | 12 +-
.../atomicrmw_faddfsub_half.ll | 11 +-
.../atomicrmw_fminfmax_double.ll | 8 +-
.../atomicrmw_fminfmax_float.ll | 11 +-
.../atomicrmw_fminfmax_half.ll | 11 +-
.../cooperative_matrix_checked.ll | 12 +-
.../long-composite-construct.ll | 6 +-
.../split_work_group_barrier_20.ll | 2 +-
.../split_work_group_barrier_spirv.ll | 10 +-
.../cooperative_matrix.ll | 12 +-
.../uniform-group-instructions.ll | 6 +-
.../SPIRV/hlsl-intrinsics/AddUint64.ll | 4 +-
llvm/test/CodeGen/SPIRV/image/sampler.ll | 2 +-
llvm/test/CodeGen/SPIRV/keep-tracked-const.ll | 6 +-
llvm/test/CodeGen/SPIRV/lit.local.cfg.bak | 7 +
llvm/test/CodeGen/SPIRV/literals.ll | 23 +-
.../constrained-comparison.ll.bak | 66 ++++
.../constrained-convert.ll.bak | 77 ++++
.../llvm-intrinsics/smul.with.overflow.ll | 6 +-
.../CodeGen/SPIRV/llvm-intrinsics/sqrt.ll | 2 +-
.../llvm-intrinsics/uadd.with.overflow.ll | 6 +-
.../llvm-intrinsics/umul.with.overflow.ll | 6 +-
.../llvm-intrinsics/usub.with.overflow.ll | 6 +-
llvm/test/CodeGen/SPIRV/opaque_pointers.ll | 2 +-
.../SPIRV/optimizations/add-check-overflow.ll | 6 +-
.../CodeGen/SPIRV/phi-multiple-preds.ll.bak | 93 +++++
.../CodeGen/SPIRV/pointers/array-skips-gep.ll | 4 +-
.../pointers/getelementptr-downcast-vector.ll | 2 +-
llvm/test/CodeGen/SPIRV/pstruct.ll | 6 +-
llvm/test/CodeGen/SPIRV/scoped_atomicrmw.ll | 16 +-
llvm/test/CodeGen/SPIRV/sitofp-with-bool.ll | 2 +-
llvm/test/CodeGen/SPIRV/struct.ll | 11 +-
.../AtomicCompareExchangeExplicit_cl20.ll | 10 +-
.../CodeGen/SPIRV/transcoding/BuildNDRange.ll | 2 +-
.../transcoding/OpVectorInsertDynamic_i16.ll | 8 +-
.../transcoding/OpenCL/atomic_cmpxchg.ll | 4 +-
.../SPIRV/transcoding/OpenCL/atomic_legacy.ll | 4 +-
.../OpenCL/atomic_work_item_fence.ll | 10 +-
.../transcoding/OpenCL/work_group_barrier.ll | 10 +-
.../SPIRV/transcoding/enqueue_kernel.ll | 56 +--
.../CodeGen/SPIRV/transcoding/group_ops.ll | 6 +-
.../CodeGen/SPIRV/transcoding/memcpy-zext.ll | 12 +-
.../spirv-private-array-initialization.ll | 8 +-
.../SPIRV/transcoding/sub_group_ballot.ll | 14 +-
.../transcoding/sub_group_clustered_reduce.ll | 16 +-
.../transcoding/sub_group_extended_types.ll | 12 +-
.../sub_group_non_uniform_arithmetic.ll | 18 +-
.../transcoding/sub_group_non_uniform_vote.ll | 16 +-
.../SPIRV/transcoding/sub_group_shuffle.ll | 14 +-
.../transcoding/sub_group_shuffle_relative.ll | 14 +-
llvm/test/CodeGen/SPIRV/uitofp-with-bool.ll | 2 +-
64 files changed, 963 insertions(+), 349 deletions(-)
create mode 100644 llvm/test/CodeGen/SPIRV/GroupAndSubgroupInstructions.spvasm
create mode 100644 llvm/test/CodeGen/SPIRV/lit.local.cfg.bak
create mode 100644 llvm/test/CodeGen/SPIRV/llvm-intrinsics/constrained-comparison.ll.bak
create mode 100644 llvm/test/CodeGen/SPIRV/llvm-intrinsics/constrained-convert.ll.bak
create mode 100644 llvm/test/CodeGen/SPIRV/phi-multiple-preds.ll.bak
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 07138c625a1af..0198e4d03d63a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -326,7 +326,13 @@ Register SPIRVGlobalRegistry::createConstInt(const ConstantInt *CI,
SPIRVType *NewType =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
MachineInstrBuilder MIB;
- if (!CI->isZero() || !ZeroAsNull) {
+ if (BitWidth == 1) {
+ MIB = MIRBuilder
+ .buildInstr(CI->isZero() ? SPIRV::OpConstantFalse
+ : SPIRV::OpConstantTrue)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ } else if (!CI->isZero() || !ZeroAsNull) {
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
.addDef(Res)
.addUse(getSPIRVTypeID(SpvType));
@@ -360,8 +366,9 @@ Register SPIRVGlobalRegistry::buildConstantInt(uint64_t Val,
unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
LLT LLTy = LLT::scalar(BitWidth);
- Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
- MF.getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ Res = MRI.createGenericVirtualRegister(LLTy);
+ MRI.setRegClass(Res, &SPIRV::iIDRegClass);
assignTypeToVReg(Ty, Res, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
EmitIR);
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
index 3499c2340a2dd..f323abe5d28a0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
@@ -216,42 +216,43 @@ def OpTypeCooperativeMatrixKHR: Op<4456, (outs TYPE:$res),
// 3.42.7 Constant-Creation Instructions
-def imm_to_i32 : SDNodeXForm<imm, [{
-return CurDAG->getTargetConstant(
- N->getValueAP().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
-}]>;
+//def imm_to_i32 : SDNodeXForm<imm, [{
+//return CurDAG->getTargetConstant(
+// N->getValueAP().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
+//}]>;
-def fimm_to_i64 : SDNodeXForm<imm, [{
-return CurDAG->getTargetConstant(
- N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
-}]>;
+//def fimm_to_i64 : SDNodeXForm<imm, [{
+//return CurDAG->getTargetConstant(
+// N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
+//}]>;
-def gi_bitcast_fimm_to_i64 : GICustomOperandRenderer<"renderFImm64">,
- GISDNodeXFormEquiv<fimm_to_i64>;
+//def gi_bitcast_fimm_to_i64 : GICustomOperandRenderer<"renderFImm64">,
+// GISDNodeXFormEquiv<fimm_to_i64>;
-def gi_bitcast_imm_to_i32 : GICustomOperandRenderer<"renderImm32">,
- GISDNodeXFormEquiv<imm_to_i32>;
+//def gi_bitcast_imm_to_i32 : GICustomOperandRenderer<"renderImm32">,
+// GISDNodeXFormEquiv<imm_to_i32>;
-def PseudoConstI: IntImmLeaf<i64, [{ return Imm.getBitWidth() <= 32; }], imm_to_i32>;
-def PseudoConstF: FPImmLeaf<f64, [{ return true; }], fimm_to_i64>;
-def ConstPseudoTrue: IntImmLeaf<i64, [{ return Imm.getBitWidth() == 1 && Imm.getZExtValue() == 1; }]>;
-def ConstPseudoFalse: IntImmLeaf<i64, [{ return Imm.getBitWidth() == 1 && Imm.getZExtValue() == 0; }]>;
-def ConstPseudoNull: IntImmLeaf<i64, [{ return Imm.isZero(); }]>;
+//def PseudoConstI: IntImmLeaf<i64, [{ return Imm.getBitWidth() <= 32; }], imm_to_i32>;
+//def PseudoConstF: FPImmLeaf<f64, [{ return true; }], fimm_to_i64>;
+//def ConstPseudoNull: IntImmLeaf<i64, [{ return Imm.isZero(); }]>;
multiclass IntFPImm<bits<16> opCode, string name> {
def I: Op<opCode, (outs iID:$dst), (ins TYPE:$type, iID:$src, variable_ops),
- "$dst = "#name#" $type", [(set iID:$dst, (assigntype PseudoConstI:$src, TYPE:$type))]>;
+ "$dst = "#name#" $type">;
+//, [(set iID:$dst, (assigntype PseudoConstI:$src, TYPE:$type))]
def F: Op<opCode, (outs fID:$dst), (ins TYPE:$type, fID:$src, variable_ops),
- "$dst = "#name#" $type", [(set fID:$dst, (assigntype PseudoConstF:$src, TYPE:$type))]>;
+ "$dst = "#name#" $type">;
+//, [(set fID:$dst, (assigntype PseudoConstF:$src, TYPE:$type))]
}
+defm OpConstant: IntFPImm<43, "OpConstant">;
+def ConstPseudoTrue: IntImmLeaf<i64, [{ return Imm.getBitWidth() == 1 && Imm.getZExtValue() == 1; }]>;
+def ConstPseudoFalse: IntImmLeaf<i64, [{ return Imm.getBitWidth() == 1 && Imm.getZExtValue() == 0; }]>;
def OpConstantTrue: Op<41, (outs iID:$dst), (ins TYPE:$src_ty), "$dst = OpConstantTrue $src_ty",
[(set iID:$dst, (assigntype ConstPseudoTrue, TYPE:$src_ty))]>;
def OpConstantFalse: Op<42, (outs iID:$dst), (ins TYPE:$src_ty), "$dst = OpConstantFalse $src_ty",
[(set iID:$dst, (assigntype ConstPseudoFalse, TYPE:$src_ty))]>;
-defm OpConstant: IntFPImm<43, "OpConstant">;
-
def OpConstantComposite: Op<44, (outs ID:$res), (ins TYPE:$type, variable_ops),
"$res = OpConstantComposite $type">;
def OpConstantCompositeContinuedINTEL: Op<6091, (outs), (ins variable_ops),
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 64d9a291f637d..8dd14a80def9d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -221,12 +221,12 @@ class SPIRVInstructionSelector : public InstructionSelector {
bool selectWaveReduceSum(Register ResVReg, const SPIRVType *ResType,
MachineInstr &I) const;
- void renderImm32(MachineInstrBuilder &MIB, const MachineInstr &I,
- int OpIdx) const;
- void renderFImm64(MachineInstrBuilder &MIB, const MachineInstr &I,
- int OpIdx) const;
+ //void renderImm32(MachineInstrBuilder &MIB, const MachineInstr &I,
+ // int OpIdx) const;
+ //void renderFImm64(MachineInstrBuilder &MIB, const MachineInstr &I,
+ // int OpIdx) const;
- bool selectConst(Register ResVReg, const SPIRVType *ResType, const APInt &Imm,
+ bool selectConst(Register ResVReg, const SPIRVType *ResType,
MachineInstr &I) const;
bool selectSelect(Register ResVReg, const SPIRVType *ResType, MachineInstr &I,
@@ -393,7 +393,8 @@ void SPIRVInstructionSelector::resetVRegsType(MachineFunction &MF) {
}
for (const auto &MBB : MF) {
for (const auto &MI : MBB) {
- //GR.invalidateMachineInstr(&I);
+ if (isPreISelGenericOpcode(MI.getOpcode()))
+ GR.erase(&MI);
if (MI.getOpcode() != SPIRV::ASSIGN_TYPE)
continue;
@@ -498,7 +499,9 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
Register DstReg = I.getOperand(0).getReg();
Register SrcReg = I.getOperand(1).getReg();
auto *Def = MRI->getVRegDef(SrcReg);
- if (isTypeFoldingSupported(Def->getOpcode())) {
+ if (isTypeFoldingSupported(Def->getOpcode()) &&
+ Def->getOpcode() != TargetOpcode::G_CONSTANT &&
+ Def->getOpcode() != TargetOpcode::G_FCONSTANT) {
bool Res = selectImpl(I, *CoverageInfo);
LLVM_DEBUG({
if (!Res && Def->getOpcode() != TargetOpcode::G_CONSTANT) {
@@ -560,6 +563,7 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
static bool mayApplyGenericSelection(unsigned Opcode) {
switch (Opcode) {
case TargetOpcode::G_CONSTANT:
+ case TargetOpcode::G_FCONSTANT:
return false;
case TargetOpcode::G_SADDO:
case TargetOpcode::G_SSUBO:
@@ -589,8 +593,8 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
return selectImpl(I, *CoverageInfo);
switch (Opcode) {
case TargetOpcode::G_CONSTANT:
- return selectConst(ResVReg, ResType, I.getOperand(1).getCImm()->getValue(),
- I);
+ case TargetOpcode::G_FCONSTANT:
+ return selectConst(ResVReg, ResType, I);
case TargetOpcode::G_GLOBAL_VALUE:
return selectGlobalValue(ResVReg, I);
case TargetOpcode::G_IMPLICIT_DEF:
@@ -2460,7 +2464,7 @@ bool SPIRVInstructionSelector::selectICmp(Register ResVReg,
CmpOpc = getICmpOpcode(Pred);
return selectCmp(ResVReg, ResType, CmpOpc, I);
}
-
+/*
void SPIRVInstructionSelector::renderFImm64(MachineInstrBuilder &MIB,
const MachineInstr &I,
int OpIdx) const {
@@ -2477,7 +2481,7 @@ void SPIRVInstructionSelector::renderImm32(MachineInstrBuilder &MIB,
"Expected G_CONSTANT");
addNumImm(I.getOperand(1).getCImm()->getValue(), MIB);
}
-
+*/
std::pair<Register, bool>
SPIRVInstructionSelector::buildI32Constant(uint32_t Val, MachineInstr &I,
const SPIRVType *ResType) const {
@@ -2711,37 +2715,24 @@ bool SPIRVInstructionSelector::selectTrunc(Register ResVReg,
bool SPIRVInstructionSelector::selectConst(Register ResVReg,
const SPIRVType *ResType,
- const APInt &Imm,
MachineInstr &I) const {
- unsigned TyOpcode = ResType->getOpcode();
- assert(TyOpcode != SPIRV::OpTypePointer || Imm.isZero());
- MachineBasicBlock &BB = *I.getParent();
- if ((TyOpcode == SPIRV::OpTypePointer || TyOpcode == SPIRV::OpTypeEvent) &&
- Imm.isZero())
- return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
- .addDef(ResVReg)
- .addUse(GR.getSPIRVTypeID(ResType))
- .constrainAllUses(TII, TRI, RBI);
- if (TyOpcode == SPIRV::OpTypeInt) {
- assert(Imm.getBitWidth() <= 64 && "Unsupported integer width!");
- const ConstantInt *CI =
- ConstantInt::get(const_cast<IntegerType *>(cast<IntegerType>(
- GR.getTypeForSPIRVType(ResType))),
- Imm.getZExtValue());
- const MachineInstr *ConstMI = GR.findMI(CI, GR.CurMF);
- Register Reg =
- (ConstMI && ConstMI != &I)
- ? ConstMI->getOperand(0).getReg()
- : GR.createConstInt(CI, I, ResType, TII, STI.isOpenCLEnv());
- return Reg == ResVReg ? true : BuildCOPY(ResVReg, Reg, I);
- }
- auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantI))
- .addDef(ResVReg)
- .addUse(GR.getSPIRVTypeID(ResType));
- // <=32-bit integers should be caught by the sdag pattern.
- assert(Imm.getBitWidth() > 32);
- addNumImm(Imm, MIB);
- return MIB.constrainAllUses(TII, TRI, RBI);
+ unsigned Opcode = I.getOpcode();
+ unsigned TpOpcode = ResType->getOpcode();
+ Register Reg;
+ if (TpOpcode == SPIRV::OpTypePointer || TpOpcode == SPIRV::OpTypeEvent) {
+ assert(Opcode == TargetOpcode::G_CONSTANT &&
+ I.getOperand(1).getCImm()->isZero());
+ MachineBasicBlock &DepMBB = I.getMF()->front();
+ MachineIRBuilder MIRBuilder(DepMBB, DepMBB.getFirstNonPHI());
+ Reg = GR.getOrCreateConstNullPtr(MIRBuilder, ResType);
+ } else if (Opcode == TargetOpcode::G_FCONSTANT) {
+ Reg = GR.getOrCreateConstFP(I.getOperand(1).getFPImm()->getValue(), I,
+ ResType, TII, STI.isOpenCLEnv());
+ } else {
+ Reg = GR.getOrCreateConstInt(I.getOperand(1).getCImm()->getZExtValue(), I,
+ ResType, TII, STI.isOpenCLEnv());
+ }
+ return Reg == ResVReg ? true : BuildCOPY(ResVReg, Reg, I);
}
bool SPIRVInstructionSelector::selectOpUndef(Register ResVReg,
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
index 520ea169fd638..aea8f340fd8f1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
@@ -146,6 +146,8 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
for (auto Opc : getTypeFoldingSupportedOpcodes())
getActionDefinitionsBuilder(Opc).custom();
+ //getActionDefinitionsBuilder(TargetOpcode::G_CONSTANT).custom();
+ //getActionDefinitionsBuilder(TargetOpcode::G_FCONSTANT).custom();
getActionDefinitionsBuilder(G_GLOBAL_VALUE).alwaysLegal();
@@ -353,8 +355,7 @@ bool SPIRVLegalizerInfo::legalizeCustom(
LostDebugLocObserver &LocObserver) const {
auto Opc = MI.getOpcode();
MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
- if (!isTypeFoldingSupported(Opc)) {
- assert(Opc == TargetOpcode::G_ICMP);
+ if (Opc == TargetOpcode::G_ICMP) {
assert(GR->getSPIRVTypeForVReg(MI.getOperand(0).getReg()));
auto &Op0 = MI.getOperand(2);
auto &Op1 = MI.getOperand(3);
diff --git a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
index 4c20688e9e983..9285ce7ba12cc 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
@@ -47,11 +47,14 @@ extern void insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB,
MachineRegisterInfo &MRI);
extern void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
- MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR);
+ MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR,
+ SPIRVType *KnownResType);
} // namespace llvm
static bool mayBeInserted(unsigned Opcode) {
switch (Opcode) {
+ // case TargetOpcode::G_CONSTANT:
+ // case TargetOpcode::G_FCONSTANT:
case TargetOpcode::G_SMAX:
case TargetOpcode::G_UMAX:
case TargetOpcode::G_SMIN:
@@ -102,20 +105,32 @@ static void processNewInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
Register ResVReg = I.getOperand(0).getReg();
// Check if the register defined by the instruction is newly generated
// or already processed
- if (MRI.getRegClassOrNull(ResVReg))
+ /*if (MRI.getRegClassOrNull(ResVReg)) {
+ if (isTypeFoldingSupported(Opcode)) {
+ insertAssignInstr(ResVReg, nullptr, ResVType, GR, MIB, MRI);
+ processInstr(I, MIB, MRI, GR, GR->getSPIRVTypeForVReg(ResVReg));
+ }
continue;
- assert(GR->getSPIRVTypeForVReg(ResVReg) == nullptr);
+ }*/
// Check if we have type defined for operands of the new instruction
- SPIRVType *ResVType = GR->getSPIRVTypeForVReg(I.getOperand(1).getReg());
+ bool IsKnownReg = MRI.getRegClassOrNull(ResVReg);
+ SPIRVType *ResVType = GR->getSPIRVTypeForVReg(
+ IsKnownReg ? ResVReg : I.getOperand(1).getReg());
if (!ResVType)
continue;
// Set type & class
- setRegClassType(ResVReg, ResVType, GR, &MRI, *GR->CurMF, true);
+ if (!IsKnownReg)
+ setRegClassType(ResVReg, ResVType, GR, &MRI, *GR->CurMF, true);
// If this is a simple operation that is to be reduced by TableGen
// definition we must apply some of pre-legalizer rules here
if (isTypeFoldingSupported(Opcode)) {
+ processInstr(I, MIB, MRI, GR, GR->getSPIRVTypeForVReg(ResVReg));
+ if (IsKnownReg && MRI.hasOneUse(ResVReg)) {
+ MachineInstr &UseMI = *MRI.use_instr_begin(ResVReg);
+ if (UseMI.getOpcode() == SPIRV::ASSIGN_TYPE)
+ continue;
+ }
insertAssignInstr(ResVReg, nullptr, ResVType, GR, MIB, MRI);
- processInstr(I, MIB, MRI, GR);
}
}
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index aea49c6a618cd..5addbc5d62d13 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -484,13 +484,18 @@ void insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpvType,
}
void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
- MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR) {
+ MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR,
+ SPIRVType *KnownResType) {
MIB.setInsertPt(*MI.getParent(), MI.getIterator());
for (auto &Op : MI.operands()) {
if (!Op.isReg() || Op.isDef())
continue;
Register OpReg = Op.getReg();
SPIRVType *SpvType = GR->getSPIRVTypeForVReg(OpReg);
+ if (!SpvType && KnownResType) {
+ SpvType = KnownResType;
+ GR->assignSPIRVTypeToVReg(KnownResType, OpReg, *MI.getMF());
+ }
assert(SpvType);
if (!MRI.getRegClassOrNull(OpReg))
MRI.setRegClass(OpReg, GR->getRegClass(SpvType));
@@ -720,7 +725,7 @@ static void processInstrsWithTypeFolding(MachineFunction &MF,
for (MachineBasicBlock &MBB : MF)
for (MachineInstr &MI : MBB)
if (isTypeFoldingSupported(MI.getOpcode()))
- processInstr(MI, MIB, MRI, GR);
+ processInstr(MI, MIB, MRI, GR, nullptr);
}
static Register
diff --git a/llvm/test/CodeGen/SPIRV/AtomicCompareExchange.ll b/llvm/test/CodeGen/SPIRV/AtomicCompareExchange.ll
index 5ce4a1954c5f2..b92c90c993c7c 100644
--- a/llvm/test/CodeGen/SPIRV/AtomicCompareExchange.ll
+++ b/llvm/test/CodeGen/SPIRV/AtomicCompareExchange.ll
@@ -1,11 +1,12 @@
-; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-; CHECK-SPIRV-DAG: %[[#Int:]] = OpTypeInt 32 0
-; CHECK-SPIRV-DAG: %[[#MemScope_CrossDevice:]] = OpConstant %[[#Int]] 0
-; CHECK-SPIRV-DAG: %[[#MemSemEqual_SeqCst:]] = OpConstant %[[#Int]] 16
-; CHECK-SPIRV-DAG: %[[#MemSemUnequal_Acquire:]] = OpConstant %[[#Int]] 2
-; CHECK-SPIRV-DAG: %[[#Constant_456:]] = OpConstant %[[#Int]] 456
-; CHECK-SPIRV-DAG: %[[#Constant_128:]] = OpConstant %[[#Int]] 128
+; CHECK-SPIRV-DAG: %[[#Int:]] = OpTypeInt 32 0
+; CHECK-SPIRV-DAG: %[[#MemScope_CrossDevice:]] = OpConstantNull %[[#Int]]
+; CHECK-SPIRV-DAG: %[[#MemSemEqual_SeqCst:]] = OpConstant %[[#Int]] 16{{$}}
+; CHECK-SPIRV-DAG: %[[#MemSemUnequal_Acquire:]] = OpConstant %[[#Int]] 2{{$}}
+; CHECK-SPIRV-DAG: %[[#Constant_456:]] = OpConstant %[[#Int]] 456{{$}}
+; CHECK-SPIRV-DAG: %[[#Constant_128:]] = OpConstant %[[#Int]] 128{{$}}
; CHECK-SPIRV-DAG: %[[#Bool:]] = OpTypeBool
; CHECK-SPIRV-DAG: %[[#Struct:]] = OpTypeStruct %[[#Int]] %[[#Bool]]
; CHECK-SPIRV-DAG: %[[#UndefStruct:]] = OpUndef %[[#Struct]]
diff --git a/llvm/test/CodeGen/SPIRV/GroupAndSubgroupInstructions.spvasm b/llvm/test/CodeGen/SPIRV/GroupAndSubgroupInstructions.spvasm
new file mode 100644
index 0000000000000..41cf085a3beec
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/GroupAndSubgroupInstructions.spvasm
@@ -0,0 +1,374 @@
+; Generated with:
+; source.cl:
+; void foo(int x, int2 coord, uint c, short s, float f, size_t n,
+; __global uint* p, read_write image2d_t image, uint4 v) {
+; work_group_all(x);
+; work_group_any(x);
+; work_group_broadcast(x, n);
+; sub_group_barrier(CLK_LOCAL_MEM_FENCE, memory_scope_sub_group);
+; sub_group_all(x);
+; sub_group_any(x);
+; sub_group_broadcast(x, c);
+; sub_group_reduce_add(x);
+; sub_group_reduce_add(f);
+; sub_group_reduce_min(x);
+; sub_group_reduce_min(c);
+; sub_group_reduce_min(f);
+; sub_group_reduce_max(x);
+; sub_group_reduce_max(c);
+; sub_group_reduce_max(f);
+; intel_sub_group_shuffle(x, c);
+; intel_sub_group_shuffle_down(x, x, c);
+; intel_sub_group_shuffle_up(x, x, c);
+; intel_sub_group_shuffle_xor(x, c);
+; intel_sub_group_block_read(p);
+; intel_sub_group_block_write(p, c);
+; intel_sub_group_block_read(image, coord);
+; intel_sub_group_block_write(image, coord, c);
+; sub_group_elect();
+; sub_group_non_uniform_all(x);
+; sub_group_non_uniform_any(x);
+; sub_group_non_uniform_all_equal(x);
+; sub_group_non_uniform_broadcast(x, c);
+; sub_group_broadcast_first(x);
+; sub_group_ballot(x);
+; sub_group_inverse_ballot(v);
+; sub_group_ballot_bit_extract(v, c);
+; sub_group_ballot_bit_count(v);
+; sub_group_ballot_inclusive_scan(v);
+; sub_group_ballot_exclusive_scan(v);
+; sub_group_ballot_find_lsb(v);
+; sub_group_ballot_find_msb(v);
+; sub_group_non_uniform_reduce_add(x);
+; sub_group_non_uniform_reduce_add(f);
+; sub_group_non_uniform_scan_inclusive_min(x);
+; sub_group_non_uniform_scan_inclusive_min(c);
+; sub_group_non_uniform_scan_inclusive_min(f);
+; sub_group_non_uniform_scan_exclusive_max(x);
+; sub_group_non_uniform_scan_exclusive_max(c);
+; sub_group_non_uniform_scan_exclusive_max(f);
+; sub_group_non_uniform_reduce_mul(x);
+; sub_group_non_uniform_reduce_mul(f);
+; sub_group_non_uniform_reduce_and(x);
+; sub_group_non_uniform_scan_inclusive_or(x);
+; sub_group_non_uniform_scan_exclusive_xor(x);
+; sub_group_non_uniform_reduce_logical_and(x);
+; sub_group_non_uniform_scan_inclusive_logical_or(x);
+; sub_group_non_uniform_scan_exclusive_logical_xor(x);
+; sub_group_rotate(c, x);
+; }
+
+; REQUIRES: spirv-dis
+; clang -cc1 -O2 -triple spir -cl-std=cl2.0 -finclude-default-header -cl-ext=+all source.cl -emit-llvm-bc -o tmp.bc
+; llvm-spirv tmp.bc --spirv-ext=+all,-SPV_KHR_untyped_pointers -o tmp.spv
+; spirv-dis tmp.spv -o llvm-spirv/test/GroupAndSubgroupInstructions.spvasm
+
+; REQUIRES: spirv-as
+; RUN: spirv-as %s --target-env spv1.3 -o %t.spv
+; RUN: spirv-val %t.spv
+; RUN: llvm-spirv -r %t.spv --spirv-target-env=CL1.2 -o %t.bc
+; RUN: llvm-dis %t.bc -o %t.ll
+; RUN: FileCheck < %t.ll %s --check-prefixes=CHECK-COMMON,CHECK-CL,CHECK-CL12
+
+; RUN: llvm-spirv -r %t.spv --spirv-target-env=CL2.0 -o %t.bc
+; RUN: llvm-dis %t.bc -o %t.ll
+; RUN: FileCheck < %t.ll %s --check-prefixes=CHECK-COMMON,CHECK-CL,CHECK-CL20
+
+; RUN: llvm-spirv -r %t.spv --spirv-target-env=SPV-IR -o %t.bc
+; RUN: llvm-dis %t.bc -o %t.ll
+; RUN: FileCheck < %t.ll %s --check-prefixes=CHECK-COMMON,CHECK-SPV-IR
+
+; RUN: llvm-spirv %t.bc --spirv-ext=+all,-SPV_KHR_untyped_pointers -o %t.rev.spv
+; RUN: spirv-val %t.rev.spv
+
+
+; CHECK-CL-DAG: declare spir_func i32 @_Z14work_group_alli(i32) #[[#Attrs:]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z14work_group_anyi(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z20work_group_broadcastjj(i32, i32) #[[#Attrs]]
+; CHECK-CL12-DAG: declare spir_func void @_Z7barrierj(i32) #[[#Attrs]]
+; CHECK-CL20-DAG: declare spir_func void @_Z17sub_group_barrierj12memory_scope(i32, i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z13sub_group_alli(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z13sub_group_anyi(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z19sub_group_broadcastjj(i32, i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z20sub_group_reduce_addi(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func float @_Z20sub_group_reduce_addf(float) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z20sub_group_reduce_mini(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z20sub_group_reduce_minj(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func float @_Z20sub_group_reduce_minf(float) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z20sub_group_reduce_maxi(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z20sub_group_reduce_maxj(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func float @_Z20sub_group_reduce_maxf(float) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z23intel_sub_group_shuffleij(i32, i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z28intel_sub_group_shuffle_downiij(i32, i32, i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z26intel_sub_group_shuffle_upiij(i32, i32, i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z27intel_sub_group_shuffle_xorij(i32, i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z26intel_sub_group_block_readPU3AS1Kj(ptr addrspace(1)) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func void @_Z27intel_sub_group_block_writePU3AS1jj(ptr addrspace(1), i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z26intel_sub_group_block_read14ocl_image2d_rwDv2_i(ptr addrspace(1), <2 x i32>) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func void @_Z27intel_sub_group_block_write14ocl_image2d_rwDv2_ij(ptr addrspace(1), <2 x i32>, i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z15sub_group_electv() #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z25sub_group_non_uniform_alli(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z25sub_group_non_uniform_anyi(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z31sub_group_non_uniform_all_equali(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z31sub_group_non_uniform_broadcastjj(i32, i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z25sub_group_broadcast_firstj(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func <4 x i32> @_Z16sub_group_balloti(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z31sub_group_ballot_inclusive_scanDv4_j(<4 x i32>) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z31sub_group_ballot_exclusive_scanDv4_j(<4 x i32>) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z25sub_group_ballot_find_lsbDv4_j(<4 x i32>) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z25sub_group_ballot_find_msbDv4_j(<4 x i32>) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z32sub_group_non_uniform_reduce_addi(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func float @_Z32sub_group_non_uniform_reduce_addf(float) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z40sub_group_non_uniform_scan_inclusive_mini(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z40sub_group_non_uniform_scan_inclusive_minj(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func float @_Z40sub_group_non_uniform_scan_inclusive_minf(float) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z40sub_group_non_uniform_scan_exclusive_maxi(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z40sub_group_non_uniform_scan_exclusive_maxj(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func float @_Z40sub_group_non_uniform_scan_exclusive_maxf(float) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z32sub_group_non_uniform_reduce_muli(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func float @_Z32sub_group_non_uniform_reduce_mulf(float) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z32sub_group_non_uniform_reduce_andi(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z39sub_group_non_uniform_scan_inclusive_ori(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z40sub_group_non_uniform_scan_exclusive_xori(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z40sub_group_non_uniform_reduce_logical_andi(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z47sub_group_non_uniform_scan_inclusive_logical_ori(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z48sub_group_non_uniform_scan_exclusive_logical_xori(i32) #[[#Attrs]]
+; CHECK-CL-DAG: declare spir_func i32 @_Z16sub_group_rotateii(i32, i32) #[[#Attrs]]
+
+; CHECK-SPV-IR: declare spir_func i1 @_Z16__spirv_GroupAllib(i32, i1) #[[#Attrs:]]
+; CHECK-SPV-IR: declare spir_func i1 @_Z16__spirv_GroupAnyib(i32, i1) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z22__spirv_GroupBroadcastiii(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func void @_Z22__spirv_ControlBarrieriii(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z17__spirv_GroupIAddiii(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func float @_Z17__spirv_GroupFAddiif(i32, i32, float) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z17__spirv_GroupSMiniii(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z17__spirv_GroupUMiniij(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func float @_Z17__spirv_GroupFMiniif(i32, i32, float) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z17__spirv_GroupSMaxiii(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z17__spirv_GroupUMaxiij(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func float @_Z17__spirv_GroupFMaxiif(i32, i32, float) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z28__spirv_SubgroupShuffleINTELij(i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z32__spirv_SubgroupShuffleDownINTELiij(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z30__spirv_SubgroupShuffleUpINTELiij(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z31__spirv_SubgroupShuffleXorINTELij(i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z35__spirv_SubgroupBlockReadINTEL_RintPU3AS1Kj(ptr addrspace(1)) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func void @_Z31__spirv_SubgroupBlockWriteINTELPU3AS1jj(ptr addrspace(1), i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z40__spirv_SubgroupImageBlockReadINTEL_RintPU3AS133__spirv_Image__void_1_0_0_0_0_0_2Dv2_i(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 2), <2 x i32>) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func void @_Z36__spirv_SubgroupImageBlockWriteINTELPU3AS133__spirv_Image__void_1_0_0_0_0_0_2Dv2_ij(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 2), <2 x i32>, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i1 @_Z28__spirv_GroupNonUniformElecti(i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i1 @_Z26__spirv_GroupNonUniformAllib(i32, i1) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i1 @_Z26__spirv_GroupNonUniformAnyib(i32, i1) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i1 @_Z31__spirv_GroupNonUniformAllEqualii(i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z32__spirv_GroupNonUniformBroadcastiij(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z37__spirv_GroupNonUniformBroadcastFirstii(i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func <4 x i32> @_Z29__spirv_GroupNonUniformBallotib(i32, i1) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z37__spirv_GroupNonUniformBallotBitCountiiDv4_j(i32, i32, <4 x i32>) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z36__spirv_GroupNonUniformBallotFindLSBiDv4_j(i32, <4 x i32>) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z36__spirv_GroupNonUniformBallotFindMSBiDv4_j(i32, <4 x i32>) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z27__spirv_GroupNonUniformIAddiii(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func float @_Z27__spirv_GroupNonUniformFAddiif(i32, i32, float) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z27__spirv_GroupNonUniformSMiniii(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z27__spirv_GroupNonUniformUMiniij(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func float @_Z27__spirv_GroupNonUniformFMiniif(i32, i32, float) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z27__spirv_GroupNonUniformSMaxiii(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z27__spirv_GroupNonUniformUMaxiij(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func float @_Z27__spirv_GroupNonUniformFMaxiif(i32, i32, float) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z27__spirv_GroupNonUniformIMuliii(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func float @_Z27__spirv_GroupNonUniformFMuliif(i32, i32, float) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z33__spirv_GroupNonUniformBitwiseAndiii(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z32__spirv_GroupNonUniformBitwiseOriii(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z33__spirv_GroupNonUniformBitwiseXoriii(i32, i32, i32) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i1 @_Z33__spirv_GroupNonUniformLogicalAndiib(i32, i32, i1) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i1 @_Z32__spirv_GroupNonUniformLogicalOriib(i32, i32, i1) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i1 @_Z33__spirv_GroupNonUniformLogicalXoriib(i32, i32, i1) #[[#Attrs]]
+; CHECK-SPV-IR: declare spir_func i32 @_Z32__spirv_GroupNonUniformRotateKHRiii(i32, i32, i32) #[[#Attrs]]
+
+; CHECK-COMMON: attributes #[[#Attrs]] =
+; CHECK-COMMON-SAME: convergent
+
+; SPIR-V
+; Version: 1.3
+; Generator: Khronos LLVM/SPIR-V Translator; 14
+; Bound: 97
+; Schema: 0
+ OpCapability Addresses
+ OpCapability Linkage
+ OpCapability Kernel
+ OpCapability ImageBasic
+ OpCapability ImageReadWrite
+ OpCapability Groups
+ OpCapability Int16
+ OpCapability GroupNonUniform
+ OpCapability GroupNonUniformVote
+ OpCapability GroupNonUniformArithmetic
+ OpCapability GroupNonUniformBallot
+ OpCapability SubgroupShuffleINTEL
+ OpCapability SubgroupBufferBlockIOINTEL
+ OpCapability SubgroupImageBlockIOINTEL
+ OpCapability GroupNonUniformRotateKHR
+ OpExtension "SPV_INTEL_subgroups"
+ OpExtension "SPV_KHR_subgroup_rotate"
+ %1 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical32 OpenCL
+ OpSource OpenCL_C 200000
+ OpName %foo "foo"
+ OpName %x "x"
+ OpName %coord "coord"
+ OpName %c "c"
+ OpName %s "s"
+ OpName %f "f"
+ OpName %n "n"
+ OpName %p "p"
+ OpName %image "image"
+ OpName %v "v"
+ OpName %entry "entry"
+ OpName %call "call"
+ OpName %call1 "call1"
+ OpName %call2 "call2"
+ OpName %call3 "call3"
+ OpName %call4 "call4"
+ OpName %call5 "call5"
+ OpName %call6 "call6"
+ OpName %call7 "call7"
+ OpName %call8 "call8"
+ OpName %call9 "call9"
+ OpName %call10 "call10"
+ OpName %call11 "call11"
+ OpName %call12 "call12"
+ OpName %call13 "call13"
+ OpName %call14 "call14"
+ OpName %call15 "call15"
+ OpName %call16 "call16"
+ OpName %call17 "call17"
+ OpName %call18 "call18"
+ OpName %call19 "call19"
+ OpName %call20 "call20"
+ OpName %call21 "call21"
+ OpName %call22 "call22"
+ OpName %call23 "call23"
+ OpName %call24 "call24"
+ OpName %call25 "call25"
+ OpName %call26 "call26"
+ OpName %call30 "call30"
+ OpName %call31 "call31"
+ OpName %call32 "call32"
+ OpName %call33 "call33"
+ OpName %call34 "call34"
+ OpName %call35 "call35"
+ OpName %call36 "call36"
+ OpName %call37 "call37"
+ OpName %call38 "call38"
+ OpName %call39 "call39"
+ OpName %call40 "call40"
+ OpName %call41 "call41"
+ OpName %call42 "call42"
+ OpName %call43 "call43"
+ OpName %call44 "call44"
+ OpName %call45 "call45"
+ OpName %call46 "call46"
+ OpName %call47 "call47"
+ OpName %call48 "call48"
+ OpName %call49 "call49"
+ OpName %call50 "call50"
+ OpDecorate %foo LinkageAttributes "foo" Export
+ OpDecorate %s FuncParamAttr Sext
+ %uint = OpTypeInt 32 0
+ %ushort = OpTypeInt 16 0
+ %uint_0 = OpConstant %uint 0
+ %uint_2 = OpConstant %uint 2
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %uint_272 = OpConstant %uint 272
+ %void = OpTypeVoid
+ %v2uint = OpTypeVector %uint 2
+ %float = OpTypeFloat 32
+%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint
+ %8 = OpTypeImage %void 2D 0 0 0 0 Unknown ReadWrite
+ %v4uint = OpTypeVector %uint 4
+ %10 = OpTypeFunction %void %uint %v2uint %uint %ushort %float %uint %_ptr_CrossWorkgroup_uint %8 %v4uint
+ %bool = OpTypeBool
+ %foo = OpFunction %void None %10
+ %x = OpFunctionParameter %uint
+ %coord = OpFunctionParameter %v2uint
+ %c = OpFunctionParameter %uint
+ %s = OpFunctionParameter %ushort
+ %f = OpFunctionParameter %float
+ %n = OpFunctionParameter %uint
+ %p = OpFunctionParameter %_ptr_CrossWorkgroup_uint
+ %image = OpFunctionParameter %8
+ %v = OpFunctionParameter %v4uint
+ %entry = OpLabel
+ %24 = OpINotEqual %bool %x %uint_0
+ %26 = OpGroupAll %bool %uint_2 %24
+ %call = OpSelect %uint %26 %uint_1 %uint_0
+ %29 = OpINotEqual %bool %x %uint_0
+ %30 = OpGroupAny %bool %uint_2 %29
+ %call1 = OpSelect %uint %30 %uint_1 %uint_0
+ %call2 = OpGroupBroadcast %uint %uint_2 %x %n
+ OpControlBarrier %uint_3 %uint_3 %uint_272
+ %35 = OpINotEqual %bool %x %uint_0
+ %36 = OpGroupAll %bool %uint_3 %35
+ %call3 = OpSelect %uint %36 %uint_1 %uint_0
+ %38 = OpINotEqual %bool %x %uint_0
+ %39 = OpGroupAny %bool %uint_3 %38
+ %call4 = OpSelect %uint %39 %uint_1 %uint_0
+ %call5 = OpGroupBroadcast %uint %uint_3 %x %c
+ %call6 = OpGroupIAdd %uint %uint_3 Reduce %x
+ %call7 = OpGroupFAdd %float %uint_3 Reduce %f
+ %call8 = OpGroupSMin %uint %uint_3 Reduce %x
+ %call9 = OpGroupUMin %uint %uint_3 Reduce %c
+ %call10 = OpGroupFMin %float %uint_3 Reduce %f
+ %call11 = OpGroupSMax %uint %uint_3 Reduce %x
+ %call12 = OpGroupUMax %uint %uint_3 Reduce %c
+ %call13 = OpGroupFMax %float %uint_3 Reduce %f
+ %call14 = OpSubgroupShuffleINTEL %uint %x %c
+ %call15 = OpSubgroupShuffleDownINTEL %uint %x %x %c
+ %call16 = OpSubgroupShuffleUpINTEL %uint %x %x %c
+ %call17 = OpSubgroupShuffleXorINTEL %uint %x %c
+ %call18 = OpSubgroupBlockReadINTEL %uint %p
+ OpSubgroupBlockWriteINTEL %p %c
+ %call19 = OpSubgroupImageBlockReadINTEL %uint %image %coord
+ OpSubgroupImageBlockWriteINTEL %image %coord %c
+ %56 = OpGroupNonUniformElect %bool %uint_3
+ %call20 = OpSelect %uint %56 %uint_1 %uint_0
+ %58 = OpINotEqual %bool %x %uint_0
+ %59 = OpGroupNonUniformAll %bool %uint_3 %58
+ %call21 = OpSelect %uint %59 %uint_1 %uint_0
+ %61 = OpINotEqual %bool %x %uint_0
+ %62 = OpGroupNonUniformAny %bool %uint_3 %61
+ %call22 = OpSelect %uint %62 %uint_1 %uint_0
+ %64 = OpGroupNonUniformAllEqual %bool %uint_3 %x
+ %call23 = OpSelect %uint %64 %uint_1 %uint_0
+ %call24 = OpGroupNonUniformBroadcast %uint %uint_3 %x %uint_1
+ %call25 = OpGroupNonUniformBroadcastFirst %uint %uint_3 %x
+ %68 = OpINotEqual %bool %x %uint_0
+ %call26 = OpGroupNonUniformBallot %v4uint %uint_3 %68
+ %call30 = OpGroupNonUniformBallotBitCount %uint %uint_3 InclusiveScan %v
+ %call31 = OpGroupNonUniformBallotBitCount %uint %uint_3 ExclusiveScan %v
+ %call32 = OpGroupNonUniformBallotFindLSB %uint %uint_3 %v
+ %call33 = OpGroupNonUniformBallotFindMSB %uint %uint_3 %v
+ %call34 = OpGroupNonUniformIAdd %uint %uint_3 Reduce %x
+ %call35 = OpGroupNonUniformFAdd %float %uint_3 Reduce %f
+ %call36 = OpGroupNonUniformSMin %uint %uint_3 InclusiveScan %x
+ %call37 = OpGroupNonUniformUMin %uint %uint_3 InclusiveScan %c
+ %call38 = OpGroupNonUniformFMin %float %uint_3 InclusiveScan %f
+ %call39 = OpGroupNonUniformSMax %uint %uint_3 ExclusiveScan %x
+ %call40 = OpGroupNonUniformUMax %uint %uint_3 ExclusiveScan %c
+ %call41 = OpGroupNonUniformFMax %float %uint_3 ExclusiveScan %f
+ %call42 = OpGroupNonUniformIMul %uint %uint_3 Reduce %x
+ %call43 = OpGroupNonUniformFMul %float %uint_3 Reduce %f
+ %call44 = OpGroupNonUniformBitwiseAnd %uint %uint_3 Reduce %x
+ %call45 = OpGroupNonUniformBitwiseOr %uint %uint_3 InclusiveScan %x
+ %call46 = OpGroupNonUniformBitwiseXor %uint %uint_3 ExclusiveScan %x
+ %87 = OpINotEqual %bool %x %uint_0
+ %88 = OpGroupNonUniformLogicalAnd %bool %uint_3 Reduce %87
+ %call47 = OpSelect %uint %88 %uint_1 %uint_0
+ %90 = OpINotEqual %bool %x %uint_0
+ %91 = OpGroupNonUniformLogicalOr %bool %uint_3 InclusiveScan %90
+ %call48 = OpSelect %uint %91 %uint_1 %uint_0
+ %93 = OpINotEqual %bool %x %uint_0
+ %94 = OpGroupNonUniformLogicalXor %bool %uint_3 ExclusiveScan %93
+ %call49 = OpSelect %uint %94 %uint_1 %uint_0
+ %call50 = OpGroupNonUniformRotateKHR %uint %uint_3 %c %x
+ OpReturn
+ OpFunctionEnd
diff --git a/llvm/test/CodeGen/SPIRV/const-array-in-struct.ll b/llvm/test/CodeGen/SPIRV/const-array-in-struct.ll
index ac39f3d28d073..862eba8b54b34 100644
--- a/llvm/test/CodeGen/SPIRV/const-array-in-struct.ll
+++ b/llvm/test/CodeGen/SPIRV/const-array-in-struct.ll
@@ -4,17 +4,18 @@
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-; CHECK-SPIRV: %[[#IntTy:]] = OpTypeInt 32 0
-; CHECK-SPIRV: %[[#Const16:]] = OpConstant %[[#IntTy]] 16
-; CHECK-SPIRV: %[[#ArrayTy:]] = OpTypeArray %[[#IntTy]] %[[#Const16]]
-; CHECK-SPIRV: %[[#StructTy:]] = OpTypeStruct %[[#ArrayTy]]
-; CHECK-SPIRV-COUNT-16: %[[#]] = OpConstant %[[#IntTy]] {{[0-9]+}}
-; CHECK-SPIRV: %[[#ConstArray:]] = OpConstantComposite %[[#ArrayTy]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]]
-; CHECK-SPIRV: %[[#]] = OpConstantComposite %[[#StructTy]] %[[#ConstArray]]
+; CHECK-SPIRV-DAG: %[[#IntTy:]] = OpTypeInt 32 0
+; CHECK-SPIRV-DAG: %[[#Const16:]] = OpConstant %[[#IntTy]] 8
+; CHECK-SPIRV-DAG: %[[#ArrayTy:]] = OpTypeArray %[[#IntTy]] %[[#Const16]]
+; CHECK-SPIRV-DAG: %[[#StructTy:]] = OpTypeStruct %[[#ArrayTy]]
+; CHECK-SPIRV-DAG: %[[#]] = OpConstantNull %[[#IntTy]]
+; CHECK-SPIRV-DAG-COUNT-7: %[[#]] = OpConstant %[[#IntTy]] {{[1-9]}}
+; CHECK-SPIRV-DAG: %[[#ConstArray:]] = OpConstantComposite %[[#ArrayTy]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]]
+; CHECK-SPIRV-DAG: %[[#]] = OpConstantComposite %[[#StructTy]] %[[#ConstArray]]
-%struct_array_16i32 = type { [16 x i32] }
+%struct_array_8i32 = type { [8 x i32] }
- at G = private unnamed_addr addrspace(1) constant %struct_array_16i32 { [16 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15] }, align 4
+ at G = private unnamed_addr addrspace(1) constant %struct_array_8i32 { [8 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7] }, align 4
define spir_kernel void @test() {
ret void
diff --git a/llvm/test/CodeGen/SPIRV/const-composite.ll b/llvm/test/CodeGen/SPIRV/const-composite.ll
index 4e304bb951670..6436261f53741 100644
--- a/llvm/test/CodeGen/SPIRV/const-composite.ll
+++ b/llvm/test/CodeGen/SPIRV/const-composite.ll
@@ -6,11 +6,11 @@
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-; CHECK-SPIRV: %[[#type_int32:]] = OpTypeInt 32 0
-; CHECK-SPIRV: %[[#const1:]] = OpConstant %[[#type_int32]] 1
-; CHECK-SPIRV: OpTypeArray %[[#]] %[[#const1:]]
-; CHECK-SPIRV: %[[#const0:]] = OpConstant %[[#type_int32]] 0
-; CHECK-SPIRV: OpConstantComposite %[[#]] %[[#const0]] %[[#const1]]
+; CHECK-SPIRV-DAG: %[[#type_int32:]] = OpTypeInt 32 0
+; CHECK-SPIRV-DAG: %[[#const1:]] = OpConstant %[[#type_int32]] 1{{$}}
+; CHECK-SPIRV-DAG: OpTypeArray %[[#]] %[[#const1:]]
+; CHECK-SPIRV-DAG: %[[#const0:]] = OpConstantNull %[[#type_int32]]
+; CHECK-SPIRV-DAG: OpConstantComposite %[[#]] %[[#const0]] %[[#const1]]
%struct = type { [1 x i64] }
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-type-basic.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-type-basic.ll
index 6073b0c2b9276..8b313983f3f90 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/debug-type-basic.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-type-basic.ll
@@ -59,17 +59,17 @@
; CHECK-SPIRV-DAG: [[type_int8:%[0-9]+]] = OpTypeInt 8 0
; CHECK-SPIRV-DAG: [[type_int16:%[0-9]+]] = OpTypeInt 16 0
; CHECK-SPIRV-DAG: [[type_int32:%[0-9]+]] = OpTypeInt 32 0
-; CHECK-SPIRV-DAG: [[encoding_signedchar:%[0-9]+]] = OpConstant [[type_int32]] 5
-; CHECK-SPIRV-DAG: [[flag_zero:%[0-9]+]] = OpConstant [[type_int32]] 0
-; CHECK-SPIRV-DAG: [[encoding_float:%[0-9]+]] = OpConstant [[type_int32]] 3
-; CHECK-SPIRV-DAG: [[size_8bit:%[0-9]+]] = OpConstant [[type_int32]] 8
-; CHECK-SPIRV-DAG: [[encoding_boolean:%[0-9]+]] = OpConstant [[type_int32]] 2
-; CHECK-SPIRV-DAG: [[size_32bit:%[0-9]+]] = OpConstant [[type_int32]] 32
-; CHECK-SPIRV-DAG: [[encoding_signed:%[0-9]+]] = OpConstant [[type_int32]] 4
-; CHECK-SPIRV-DAG: [[size_16bit:%[0-9]+]] = OpConstant [[type_int32]] 16
-; CHECK-SPIRV-DAG: [[size_64bit:%[0-9]+]] = OpConstant [[type_int32]] 64
-; CHECK-SPIRV-DAG: [[encoding_unsigned:%[0-9]+]] = OpConstant [[type_int32]] 6
-; CHECK-SPIRV-DAG: [[encoding_unsignedchar:%[0-9]+]] = OpConstant [[type_int32]] 7
+; CHECK-SPIRV-DAG: [[encoding_signedchar:%[0-9]+]] = OpConstant [[type_int32]] 5{{$}}
+; CHECK-SPIRV-DAG: [[flag_zero:%[0-9]+]] = OpConstantNull [[type_int32]]
+; CHECK-SPIRV-DAG: [[encoding_float:%[0-9]+]] = OpConstant [[type_int32]] 3{{$}}
+; CHECK-SPIRV-DAG: [[size_8bit:%[0-9]+]] = OpConstant [[type_int32]] 8{{$}}
+; CHECK-SPIRV-DAG: [[encoding_boolean:%[0-9]+]] = OpConstant [[type_int32]] 2{{$}}
+; CHECK-SPIRV-DAG: [[size_32bit:%[0-9]+]] = OpConstant [[type_int32]] 32{{$}}
+; CHECK-SPIRV-DAG: [[encoding_signed:%[0-9]+]] = OpConstant [[type_int32]] 4{{$}}
+; CHECK-SPIRV-DAG: [[size_16bit:%[0-9]+]] = OpConstant [[type_int32]] 16{{$}}
+; CHECK-SPIRV-DAG: [[size_64bit:%[0-9]+]] = OpConstant [[type_int32]] 64{{$}}
+; CHECK-SPIRV-DAG: [[encoding_unsigned:%[0-9]+]] = OpConstant [[type_int32]] 6{{$}}
+; CHECK-SPIRV-DAG: [[encoding_unsignedchar:%[0-9]+]] = OpConstant [[type_int32]] 7{{$}}
; CHECK-SPIRV-DAG: OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugTypeBasic [[str_bool]] [[size_8bit]] [[encoding_boolean]] [[flag_zero]]
; CHECK-SPIRV-DAG: OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugTypeBasic [[str_int]] [[size_32bit]] [[encoding_signed]] [[flag_zero]]
; CHECK-SPIRV-DAG: OpExtInst [[type_void]] [[ext_inst_non_semantic]] DebugTypeBasic [[str_short]] [[size_16bit]] [[encoding_signed]] [[flag_zero]]
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll
index 2b29b4fca5671..d87ac01025915 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll
@@ -7,11 +7,11 @@
; CHECK-MIR-DAG: [[i32type:%[0-9]+\:type]] = OpTypeInt 32, 0
; CHECK-MIR-DAG: [[void_type:%[0-9]+\:type\(s64\)]] = OpTypeVoid
; CHECK-MIR-DAG: [[i32_8:%[0-9]+\:iid]] = OpConstantI [[i32type]], 8{{$}}
-; CHECK-MIR-DAG: [[i32_0:%[0-9]+\:pid]] = OpConstantNull
+; CHECK-MIR-DAG: [[i32_0:%[0-9]+\:iid\(s32\)]] = OpConstantNull [[i32type]]
; CHECK-MIR-DAG: [[i32_5:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 5{{$}}
; CHECK-MIR-DAG: [[enc_float:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 3{{$}}
; CHECK-MIR-DAG: [[enc_boolean:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 2{{$}}
-; CHECK-MIR-DAG: [[bool:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_8]], [[enc_boolean]], [[i32_0]]
+; CHECK-MIR-DAG: [[bool:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, %[[#]], [[i32_8]], [[enc_boolean]], [[i32_0]]
; CHECK-MIR-DAG: [[i32_16:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 16{{$}}
; CHECK-MIR-DAG: [[enc_signed:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 4{{$}}
; CHECK-MIR-DAG: [[short:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_16]], [[enc_signed]], [[i32_0]]
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_add/atomicrmw_faddfsub_double.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_add/atomicrmw_faddfsub_double.ll
index c2ed2f8f62fc8..5d53ea06232c0 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_add/atomicrmw_faddfsub_double.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_add/atomicrmw_faddfsub_double.ll
@@ -8,11 +8,11 @@
; CHECK: Extension "SPV_EXT_shader_atomic_float_add"
; CHECK-DAG: %[[TyFP64:[0-9]+]] = OpTypeFloat 64
; CHECK-DAG: %[[TyInt32:[0-9]+]] = OpTypeInt 32 0
-; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstant %[[TyFP64]] 0
-; CHECK-DAG: %[[Const42:[0-9]+]] = OpConstant %[[TyFP64]] 42
+; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstantNull %[[TyFP64]]
+; CHECK-DAG: %[[Const42:[0-9]+]] = OpConstant %[[TyFP64]] 42{{$}}
; CHECK-DAG: %[[ScopeAllSvmDevices:[0-9]+]] = OpConstantNull %[[TyInt32]]
-; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16
-; CHECK-DAG: %[[ScopeDevice:[0-9]+]] = OpConstant %[[TyInt32]] 1
+; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16{{$}}
+; CHECK-DAG: %[[ScopeDevice:[0-9]+]] = OpConstant %[[TyInt32]] 1{{$}}
; CHECK-DAG: %[[TyFP64Ptr:[0-9]+]] = OpTypePointer {{[a-zA-Z]+}} %[[TyFP64]]
; CHECK-DAG: %[[DblPtr:[0-9]+]] = OpVariable %[[TyFP64Ptr]] {{[a-zA-Z]+}} %[[Const0]]
; CHECK: OpAtomicFAddEXT %[[TyFP64]] %[[DblPtr]] %[[ScopeAllSvmDevices]] %[[MemSeqCst]] %[[Const42]]
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_add/atomicrmw_faddfsub_float.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_add/atomicrmw_faddfsub_float.ll
index c6c8afc47dee3..1fcaca0ae36f2 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_add/atomicrmw_faddfsub_float.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_add/atomicrmw_faddfsub_float.ll
@@ -12,13 +12,13 @@
; CHECK: Extension "SPV_EXT_shader_atomic_float_add"
; CHECK-DAG: %[[TyFP32:[0-9]+]] = OpTypeFloat 32
; CHECK-DAG: %[[TyInt32:[0-9]+]] = OpTypeInt 32 0
-; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstant %[[TyFP32]] 0
-; CHECK-DAG: %[[Const42:[0-9]+]] = OpConstant %[[TyFP32]] 42
+; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstantNull %[[TyFP32]]
+; CHECK-DAG: %[[Const42:[0-9]+]] = OpConstant %[[TyFP32]] 42{{$}}
; CHECK-DAG: %[[ScopeAllSvmDevices:[0-9]+]] = OpConstantNull %[[TyInt32]]
-; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16
-; CHECK-DAG: %[[ScopeDevice:[0-9]+]] = OpConstant %[[TyInt32]] 1
-; CHECK-DAG: %[[ScopeWorkgroup:[0-9]+]] = OpConstant %[[TyInt32]] 2
-; CHECK-DAG: %[[WorkgroupMemory:[0-9]+]] = OpConstant %[[TyInt32]] 512
+; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16{{$}}
+; CHECK-DAG: %[[ScopeDevice:[0-9]+]] = OpConstant %[[TyInt32]] 1{{$}}
+; CHECK-DAG: %[[ScopeWorkgroup:[0-9]+]] = OpConstant %[[TyInt32]] 2{{$}}
+; CHECK-DAG: %[[WorkgroupMemory:[0-9]+]] = OpConstant %[[TyInt32]] 512{{$}}
; CHECK-DAG: %[[TyFP32Ptr:[0-9]+]] = OpTypePointer {{[a-zA-Z]+}} %[[TyFP32]]
; CHECK-DAG: %[[DblPtr:[0-9]+]] = OpVariable %[[TyFP32Ptr]] {{[a-zA-Z]+}} %[[Const0]]
; CHECK: OpAtomicFAddEXT %[[TyFP32]] %[[DblPtr]] %[[ScopeAllSvmDevices]] %[[MemSeqCst]] %[[Const42]]
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_add/atomicrmw_faddfsub_half.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_add/atomicrmw_faddfsub_half.ll
index 2c938409846d3..b1485de25633d 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_add/atomicrmw_faddfsub_half.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_add/atomicrmw_faddfsub_half.ll
@@ -11,11 +11,11 @@
; CHECK: Extension "SPV_EXT_shader_atomic_float16_add"
; CHECK-DAG: %[[TyFP16:[0-9]+]] = OpTypeFloat 16
; CHECK-DAG: %[[TyInt32:[0-9]+]] = OpTypeInt 32 0
-; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstant %[[TyFP16]] 0
-; CHECK-DAG: %[[Const42:[0-9]+]] = OpConstant %[[TyFP16]] 20800
+; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstantNull %[[TyFP16]]
+; CHECK-DAG: %[[Const42:[0-9]+]] = OpConstant %[[TyFP16]] 20800{{$}}
; CHECK-DAG: %[[ScopeAllSvmDevices:[0-9]+]] = OpConstantNull %[[TyInt32]]
-; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16
-; CHECK-DAG: %[[ScopeDevice:[0-9]+]] = OpConstant %[[TyInt32]] 1
+; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16{{$}}
+; CHECK-DAG: %[[ScopeDevice:[0-9]+]] = OpConstant %[[TyInt32]] 1{{$}}
; CHECK-DAG: %[[TyFP16Ptr:[0-9]+]] = OpTypePointer {{[a-zA-Z]+}} %[[TyFP16]]
; CHECK-DAG: %[[DblPtr:[0-9]+]] = OpVariable %[[TyFP16Ptr]] {{[a-zA-Z]+}} %[[Const0]]
; CHECK: OpAtomicFAddEXT %[[TyFP16]] %[[DblPtr]] %[[ScopeAllSvmDevices]] %[[MemSeqCst]] %[[Const42]]
@@ -23,9 +23,6 @@
; CHECK: OpAtomicFAddEXT %[[TyFP16]] %[[DblPtr]] %[[ScopeAllSvmDevices]] %[[MemSeqCst]] %[[Const42Neg]]
; CHECK: OpAtomicFAddEXT %[[TyFP16]] %[[DblPtr]] %[[ScopeDevice]] %[[MemSeqCst]] %[[Const42]]
-target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
-target triple = "spir64"
-
@f = common dso_local local_unnamed_addr addrspace(1) global half 0.000000e+00, align 8
define dso_local spir_func void @test1() local_unnamed_addr {
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_min_max/atomicrmw_fminfmax_double.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_min_max/atomicrmw_fminfmax_double.ll
index fdc05f4eac06b..b5b4bbccfed66 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_min_max/atomicrmw_fminfmax_double.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_min_max/atomicrmw_fminfmax_double.ll
@@ -8,11 +8,11 @@
; CHECK: Extension "SPV_EXT_shader_atomic_float_min_max"
; CHECK-DAG: %[[TyFP64:[0-9]+]] = OpTypeFloat 64
; CHECK-DAG: %[[TyInt32:[0-9]+]] = OpTypeInt 32 0
-; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstant %[[TyFP64]] 0
-; CHECK-DAG: %[[Const42:[0-9]+]] = OpConstant %[[TyFP64]] 42
+; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstantNull %[[TyFP64]]
+; CHECK-DAG: %[[Const42:[0-9]+]] = OpConstant %[[TyFP64]] 42{{$}}
; CHECK-DAG: %[[ScopeAllSvmDevices:[0-9]+]] = OpConstantNull %[[TyInt32]]
-; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16
-; CHECK-DAG: %[[ScopeDevice:[0-9]+]] = OpConstant %[[TyInt32]] 1
+; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16{{$}}
+; CHECK-DAG: %[[ScopeDevice:[0-9]+]] = OpConstant %[[TyInt32]] 1{{$}}
; CHECK-DAG: %[[TyFP64Ptr:[0-9]+]] = OpTypePointer {{[a-zA-Z]+}} %[[TyFP64]]
; CHECK-DAG: %[[DblPtr:[0-9]+]] = OpVariable %[[TyFP64Ptr]] {{[a-zA-Z]+}} %[[Const0]]
; CHECK: OpAtomicFMinEXT %[[TyFP64]] %[[DblPtr]] %[[ScopeAllSvmDevices]] %[[MemSeqCst]] %[[Const42]]
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_min_max/atomicrmw_fminfmax_float.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_min_max/atomicrmw_fminfmax_float.ll
index a7ff448a98b98..23da888d91ff4 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_min_max/atomicrmw_fminfmax_float.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_min_max/atomicrmw_fminfmax_float.ll
@@ -8,11 +8,11 @@
; CHECK: Extension "SPV_EXT_shader_atomic_float_min_max"
; CHECK-DAG: %[[TyFP32:[0-9]+]] = OpTypeFloat 32
; CHECK-DAG: %[[TyInt32:[0-9]+]] = OpTypeInt 32 0
-; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstant %[[TyFP32]] 0
-; CHECK-DAG: %[[Const42:[0-9]+]] = OpConstant %[[TyFP32]] 42
+; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstantNull %[[TyFP32]]
+; CHECK-DAG: %[[Const42:[0-9]+]] = OpConstant %[[TyFP32]] 42{{$}}
; CHECK-DAG: %[[ScopeAllSvmDevices:[0-9]+]] = OpConstantNull %[[TyInt32]]
-; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16
-; CHECK-DAG: %[[ScopeDevice:[0-9]+]] = OpConstant %[[TyInt32]] 1
+; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16{{$}}
+; CHECK-DAG: %[[ScopeDevice:[0-9]+]] = OpConstant %[[TyInt32]] 1{{$}}
; CHECK-DAG: %[[TyFP32Ptr:[0-9]+]] = OpTypePointer {{[a-zA-Z]+}} %[[TyFP32]]
; CHECK-DAG: %[[DblPtr:[0-9]+]] = OpVariable %[[TyFP32Ptr]] {{[a-zA-Z]+}} %[[Const0]]
; CHECK: OpAtomicFMinEXT %[[TyFP32]] %[[DblPtr]] %[[ScopeAllSvmDevices]] %[[MemSeqCst]] %[[Const42]]
@@ -20,9 +20,6 @@
; CHECK: OpAtomicFMinEXT %[[TyFP32]] %[[DblPtr]] %[[ScopeDevice]] %[[MemSeqCst]] %[[Const42]]
; CHECK: OpAtomicFMaxEXT %[[TyFP32]] %[[DblPtr]] %[[ScopeDevice]] %[[MemSeqCst]] %[[Const42]]
-target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
-target triple = "spir64"
-
@f = common dso_local local_unnamed_addr addrspace(1) global float 0.000000e+00, align 8
define dso_local spir_func void @test1() local_unnamed_addr {
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_min_max/atomicrmw_fminfmax_half.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_min_max/atomicrmw_fminfmax_half.ll
index d5576d1911a8b..357bc40a9d02c 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_min_max/atomicrmw_fminfmax_half.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_shader_atomic_float_min_max/atomicrmw_fminfmax_half.ll
@@ -8,11 +8,11 @@
; CHECK: Extension "SPV_EXT_shader_atomic_float_min_max"
; CHECK-DAG: %[[TyFP16:[0-9]+]] = OpTypeFloat 16
; CHECK-DAG: %[[TyInt32:[0-9]+]] = OpTypeInt 32 0
-; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstant %[[TyFP16]] 0
-; CHECK-DAG: %[[ConstHalf:[0-9]+]] = OpConstant %[[TyFP16]] 20800
+; CHECK-DAG: %[[Const0:[0-9]+]] = OpConstantNull %[[TyFP16]]
+; CHECK-DAG: %[[ConstHalf:[0-9]+]] = OpConstant %[[TyFP16]] 20800{{$}}
; CHECK-DAG: %[[ScopeAllSvmDevices:[0-9]+]] = OpConstantNull %[[TyInt32]]
-; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16
-; CHECK-DAG: %[[ScopeDevice:[0-9]+]] = OpConstant %[[TyInt32]] 1
+; CHECK-DAG: %[[MemSeqCst:[0-9]+]] = OpConstant %[[TyInt32]] 16{{$}}
+; CHECK-DAG: %[[ScopeDevice:[0-9]+]] = OpConstant %[[TyInt32]] 1{{$}}
; CHECK-DAG: %[[TyFP16Ptr:[0-9]+]] = OpTypePointer {{[a-zA-Z]+}} %[[TyFP16]]
; CHECK-DAG: %[[DblPtr:[0-9]+]] = OpVariable %[[TyFP16Ptr]] {{[a-zA-Z]+}} %[[Const0]]
; CHECK: OpAtomicFMinEXT %[[TyFP16]] %[[DblPtr]] %[[ScopeAllSvmDevices]] %[[MemSeqCst]] %[[ConstHalf]]
@@ -20,9 +20,6 @@
; CHECK: OpAtomicFMinEXT %[[TyFP16]] %[[DblPtr]] %[[ScopeDevice]] %[[MemSeqCst]] %[[ConstHalf]]
; CHECK: OpAtomicFMaxEXT %[[TyFP16]] %[[DblPtr]] %[[ScopeDevice]] %[[MemSeqCst]] %[[ConstHalf]]
-target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
-target triple = "spir64"
-
@f = common dso_local local_unnamed_addr addrspace(1) global half 0.000000e+00, align 8
define dso_local spir_func void @test1() local_unnamed_addr {
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_joint_matrix/cooperative_matrix_checked.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_joint_matrix/cooperative_matrix_checked.ll
index a4b2c4be5084b..33d5a91c54a36 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_joint_matrix/cooperative_matrix_checked.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_joint_matrix/cooperative_matrix_checked.ll
@@ -10,12 +10,12 @@
; CHECK-DAG: Extension "SPV_INTEL_joint_matrix"
; CHECK-DAG: %[[#Int8Ty:]] = OpTypeInt 8 0
; CHECK-DAG: %[[#Int32Ty:]] = OpTypeInt 32 0
-; CHECK-DAG: %[[#Const12:]] = OpConstant %[[#Int32Ty]] 12
-; CHECK-DAG: %[[#Const48:]] = OpConstant %[[#Int32Ty]] 48
-; CHECK-DAG: %[[#Const0:]] = OpConstant %[[#Int32Ty]] 0
-; CHECK-DAG: %[[#Const3:]] = OpConstant %[[#Int32Ty]] 3
-; CHECK-DAG: %[[#Const2:]] = OpConstant %[[#Int32Ty]] 2
-; CHECK-DAG: %[[#Const1:]] = OpConstant %[[#Int32Ty]] 1
+; CHECK-DAG: %[[#Const12:]] = OpConstant %[[#Int32Ty]] 12{{$}}
+; CHECK-DAG: %[[#Const48:]] = OpConstant %[[#Int32Ty]] 48{{$}}
+; CHECK-DAG: %[[#Const0:]] = OpConstantNull %[[#Int32Ty]]
+; CHECK-DAG: %[[#Const3:]] = OpConstant %[[#Int32Ty]] 3{{$}}
+; CHECK-DAG: %[[#Const2:]] = OpConstant %[[#Int32Ty]] 2{{$}}
+; CHECK-DAG: %[[#Const1:]] = OpConstant %[[#Int32Ty]] 1{{$}}
; CHECK-DAG: %[[#MatTy1:]] = OpTypeCooperativeMatrixKHR %[[#Int32Ty]] %[[#Const3]] %[[#Const12]] %[[#Const12]] %[[#Const2]]
; CHECK-DAG: %[[#MatTy2:]] = OpTypeCooperativeMatrixKHR %[[#Int8Ty]] %[[#Const3]] %[[#Const12]] %[[#Const48]] %[[#Const0]]
; CHECK-DAG: %[[#MatTy3:]] = OpTypeCooperativeMatrixKHR %[[#Int8Ty]] %[[#Const2]] %[[#Const48]] %[[#Const12]] %[[#Const1]]
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_long_composites/long-composite-construct.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_long_composites/long-composite-construct.ll
index 6c12307daa26e..07839d001be65 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_long_composites/long-composite-construct.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_long_composites/long-composite-construct.ll
@@ -11,9 +11,9 @@
; CHECK: %[[#TStruct:]] = OpTypeStruct %[[#TInt8]] %[[#TInt32]] %[[#TInt8]] %[[#TInt8]]
; CHECK-NEXT: OpTypeStructContinuedINTEL %[[#TInt8]] %[[#TInt8]] %[[#TInt8]] %[[#TInt8]] %[[#TInt8]] %[[#TInt8]] %[[#TInt8]]{{$}}
-; CHECK-DAG: %[[#Const0:]] = OpConstant %[[#TInt8]] 0
-; CHECK-DAG: %[[#Const1:]] = OpConstant %[[#TInt8]] 1
-; CHECK-DAG: %[[#Const2:]] = OpConstant %[[#TInt32]] 2
+; CHECK-DAG: %[[#Const0:]] = OpConstantNull %[[#TInt8]]
+; CHECK-DAG: %[[#Const1:]] = OpConstant %[[#TInt8]] 1{{$}}
+; CHECK-DAG: %[[#Const2:]] = OpConstant %[[#TInt32]] 2{{$}}
; CHECK: OpCompositeConstruct %[[#TStruct]] %[[#Const1]] %[[#Const2]] %[[#Const0]] %[[#Const0]]
; CHECK-NEXT: OpCompositeConstructContinuedINTEL %[[#Const0]] %[[#Const0]] %[[#Const0]] %[[#Const0]] %[[#Const0]] %[[#Const0]] %[[#Const0]] %[[#Const0]]{{$}}
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_split_barrier/split_work_group_barrier_20.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_split_barrier/split_work_group_barrier_20.ll
index d738a39487831..35cee1d963d8b 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_split_barrier/split_work_group_barrier_20.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_split_barrier/split_work_group_barrier_20.ll
@@ -41,7 +41,7 @@
; CHECK-DAG: %[[#SCOPE_WORK_GROUP:]] = OpConstant %[[#UINT]] 2{{$}}
; CHECK-DAG: %[[#SCOPE_INVOCATION:]] = OpConstant %[[#UINT]] 4{{$}}
; CHECK-DAG: %[[#SCOPE_DEVICE:]] = OpConstant %[[#UINT]] 1{{$}}
-; CHECK-DAG: %[[#SCOPE_CROSS_DEVICE:]] = OpConstant %[[#UINT]] 0{{$}}
+; CHECK-DAG: %[[#SCOPE_CROSS_DEVICE:]] = OpConstantNull %[[#UINT]]{{$}}
; CHECK-DAG: %[[#SCOPE_SUBGROUP:]] = OpConstant %[[#UINT]] 3{{$}}
;
; Memory Semantics:
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_split_barrier/split_work_group_barrier_spirv.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_split_barrier/split_work_group_barrier_spirv.ll
index 9ca08b649a228..5f2090cf55f82 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_split_barrier/split_work_group_barrier_spirv.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_split_barrier/split_work_group_barrier_spirv.ll
@@ -38,11 +38,11 @@
; CHECK: %[[#UINT:]] = OpTypeInt 32 0
;
; Scopes:
-; CHECK-DAG: %[[#SCOPE_WORK_GROUP:]] = OpConstant %[[#UINT]] 2
-; CHECK-DAG: %[[#SCOPE_INVOCATION:]] = OpConstant %[[#UINT]] 4
-; CHECK-DAG: %[[#SCOPE_DEVICE:]] = OpConstant %[[#UINT]] 1
-; CHECK-DAG: %[[#SCOPE_CROSS_DEVICE:]] = OpConstant %[[#UINT]] 0
-; CHECK-DAG: %[[#SCOPE_SUBGROUP:]] = OpConstant %[[#UINT]] 3
+; CHECK-DAG: %[[#SCOPE_WORK_GROUP:]] = OpConstant %[[#UINT]] 2{{$}}
+; CHECK-DAG: %[[#SCOPE_INVOCATION:]] = OpConstant %[[#UINT]] 4{{$}}
+; CHECK-DAG: %[[#SCOPE_DEVICE:]] = OpConstant %[[#UINT]] 1{{$}}
+; CHECK-DAG: %[[#SCOPE_CROSS_DEVICE:]] = OpConstantNull %[[#UINT]]
+; CHECK-DAG: %[[#SCOPE_SUBGROUP:]] = OpConstant %[[#UINT]] 3{{$}}
;
; Memory Semantics:
; 0x2 Acquire + 0x100 WorkgroupMemory
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_cooperative_matrix/cooperative_matrix.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_cooperative_matrix/cooperative_matrix.ll
index 45e71d44fbf60..a620423b97416 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_cooperative_matrix/cooperative_matrix.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_cooperative_matrix/cooperative_matrix.ll
@@ -11,12 +11,12 @@
; CHECK: OpExtension "SPV_KHR_cooperative_matrix"
; CHECK-DAG: %[[#Int32Ty:]] = OpTypeInt 32 0
-; CHECK-DAG: %[[#Const12:]] = OpConstant %[[#Int32Ty]] 12
-; CHECK-DAG: %[[#Const48:]] = OpConstant %[[#Int32Ty]] 48
-; CHECK-DAG: %[[#Const3:]] = OpConstant %[[#Int32Ty]] 3
-; CHECK-DAG: %[[#Const2:]] = OpConstant %[[#Int32Ty]] 2
-; CHECK-DAG: %[[#Const1:]] = OpConstant %[[#Int32Ty]] 1
-; CHECK-DAG: %[[#Const0:]] = OpConstant %[[#Int32Ty]] 0
+; CHECK-DAG: %[[#Const12:]] = OpConstant %[[#Int32Ty]] 12{{$}}
+; CHECK-DAG: %[[#Const48:]] = OpConstant %[[#Int32Ty]] 48{{$}}
+; CHECK-DAG: %[[#Const3:]] = OpConstant %[[#Int32Ty]] 3{{$}}
+; CHECK-DAG: %[[#Const2:]] = OpConstant %[[#Int32Ty]] 2{{$}}
+; CHECK-DAG: %[[#Const1:]] = OpConstant %[[#Int32Ty]] 1{{$}}
+; CHECK-DAG: %[[#Const0:]] = OpConstantNull %[[#Int32Ty]]
; CHECK-DAG: %[[#MatTy1:]] = OpTypeCooperativeMatrixKHR %[[#Int32Ty]] %[[#Const3]] %[[#Const12]] %[[#Const12]] %[[#Const2]]
; CHECK-DAG: %[[#MatTy2:]] = OpTypeCooperativeMatrixKHR %[[#Int32Ty]] %[[#Const3]] %[[#Const12]] %[[#Const48]] %[[#Const0]]
; CHECK-DAG: %[[#MatTy3:]] = OpTypeCooperativeMatrixKHR %[[#Int32Ty]] %[[#Const3]] %[[#Const48]] %[[#Const12]] %[[#Const1]]
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_uniform_group_instructions/uniform-group-instructions.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_uniform_group_instructions/uniform-group-instructions.ll
index 96e74149f44db..baae876df2d70 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_uniform_group_instructions/uniform-group-instructions.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_uniform_group_instructions/uniform-group-instructions.ll
@@ -9,9 +9,9 @@
; CHECK-DAG: %[[TyInt:[0-9]+]] = OpTypeInt 32 0
; CHECK-DAG: %[[TyBool:[0-9]+]] = OpTypeBool
; CHECK-DAG: %[[TyFloat:[0-9]+]] = OpTypeFloat 16
-; CHECK-DAG: %[[Scope:[0-9]+]] = OpConstant %[[TyInt]] 2
-; CHECK-DAG: %[[ConstInt:[0-9]+]] = OpConstant %[[TyInt]] 0
-; CHECK-DAG: %[[ConstFloat:[0-9]+]] = OpConstant %[[TyFloat]] 0
+; CHECK-DAG: %[[Scope:[0-9]+]] = OpConstant %[[TyInt]] 2{{$}}
+; CHECK-DAG: %[[ConstInt:[0-9]+]] = OpConstantNull %[[TyInt]]
+; CHECK-DAG: %[[ConstFloat:[0-9]+]] = OpConstantNull %[[TyFloat]]
; CHECK-DAG: %[[ConstBool:[0-9]+]] = OpConstantFalse %[[TyBool]]
; CHECK: OpGroupBitwiseAndKHR %[[TyInt]] %[[Scope]] 0 %[[ConstInt]]
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/AddUint64.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/AddUint64.ll
index 6521699a242ed..1e7243e37b4a9 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/AddUint64.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/AddUint64.ll
@@ -7,10 +7,10 @@
; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32 0
; CHECK-DAG: %[[#vec2_int_32:]] = OpTypeVector %[[#int_32]] 2
; CHECK-DAG: %[[#bool:]] = OpTypeBool
-; CHECK-DAG: %[[#const_i32_1:]] = OpConstant %[[#int_32]] 1
+; CHECK-DAG: %[[#const_i32_1:]] = OpConstant %[[#int_32]] 1{{$}}
; CHECK-DAG: %[[#struct_i32_i32:]] = OpTypeStruct %[[#int_32]] %[[#int_32]]
; CHECK-DAG: %[[#func_v2i32_v2i32_v2i32:]] = OpTypeFunction %[[#vec2_int_32]] %[[#vec2_int_32]] %[[#vec2_int_32]]
-; CHECK-DAG: %[[#const_i32_0:]] = OpConstant %[[#int_32]] 0
+; CHECK-DAG: %[[#const_i32_0:]] = OpConstant %[[#int_32]] 0{{$}}
; CHECK-DAG: %[[#undef_v2i32:]] = OpUndef %[[#vec2_int_32]]
; CHECK-DAG: %[[#vec4_int_32:]] = OpTypeVector %[[#int_32]] 4
; CHECK-DAG: %[[#vec2_bool:]] = OpTypeVector %[[#bool]] 2
diff --git a/llvm/test/CodeGen/SPIRV/image/sampler.ll b/llvm/test/CodeGen/SPIRV/image/sampler.ll
index f6ac3510ab675..5e2a2978a9c32 100644
--- a/llvm/test/CodeGen/SPIRV/image/sampler.ll
+++ b/llvm/test/CodeGen/SPIRV/image/sampler.ll
@@ -6,7 +6,7 @@
; CHECK-DAG: %[[#ptrv4i32:]] = OpTypePointer CrossWorkgroup %[[#v4i32]]
; CHECK-DAG: %[[#float:]] = OpTypeFloat 32
; CHECK-DAG: %[[#typesampled:]] = OpTypeSampledImage
-; CHECK-DAG: %[[#const0:]] = OpConstant %[[#float]] 0
+; CHECK-DAG: %[[#const0:]] = OpConstantNull %[[#float]]
; CHECK: OpFunction
; CHECK: OpFunctionParameter
; CHECK: %[[#arg1:]] = OpFunctionParameter
diff --git a/llvm/test/CodeGen/SPIRV/keep-tracked-const.ll b/llvm/test/CodeGen/SPIRV/keep-tracked-const.ll
index 61d06fe2752e1..ee3d09e4876af 100644
--- a/llvm/test/CodeGen/SPIRV/keep-tracked-const.ll
+++ b/llvm/test/CodeGen/SPIRV/keep-tracked-const.ll
@@ -4,10 +4,8 @@
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
; CHECK-SPIRV-DAG: %[[#Int:]] = OpTypeInt 32 0
-; CHECK-SPIRV-DAG: %[[#C0:]] = OpConstant %[[#Int]] 0
-; CHECK-SPIRV-DAG: %[[#C1:]] = OpConstant %[[#Int]] 1
-; CHECK-SPIRV: OpSelect %[[#Int]] %[[#]] %[[#C1]] %[[#C0]]
-
+; CHECK-SPIRV-DAG: %[[#C0:]] = OpConstantNull %[[#Int]]
+; CHECK-SPIRV-DAG: %[[#C1:]] = OpConstant %[[#Int]] 1{{$}}
define spir_kernel void @foo() {
entry:
diff --git a/llvm/test/CodeGen/SPIRV/lit.local.cfg.bak b/llvm/test/CodeGen/SPIRV/lit.local.cfg.bak
new file mode 100644
index 0000000000000..00f50fb6f1cff
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/lit.local.cfg.bak
@@ -0,0 +1,7 @@
+if not "SPIRV" in config.root.targets:
+ config.unsupported = True
+
+if config.spirv_tools_tests:
+ config.available_features.add("spirv-tools")
+ config.substitutions.append(("spirv-dis", os.path.join(config.llvm_tools_dir, "spirv-dis")))
+ config.substitutions.append(("spirv-val", os.path.join(config.llvm_tools_dir, "spirv-val")))
diff --git a/llvm/test/CodeGen/SPIRV/literals.ll b/llvm/test/CodeGen/SPIRV/literals.ll
index 4f5aa7d4fa0e8..987efba19934d 100644
--- a/llvm/test/CodeGen/SPIRV/literals.ll
+++ b/llvm/test/CodeGen/SPIRV/literals.ll
@@ -4,35 +4,28 @@
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-; CHECK: %[[#F32:]] = OpTypeFloat 32
-; CHECK: %[[#F64:]] = OpTypeFloat 64
+; CHECK-DAG: %[[#F32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#F64:]] = OpTypeFloat 64
+; CHECK-DAG: OpConstant %[[#F32]] 0.5{{$}}
+; CHECK-DAG: OpConstant %[[#F64]] 0.5{{$}}
+; CHECK-DAG: OpConstant %[[#F32]] 1.0000016166037976e-39{{$}}
+; CHECK-DAG: OpConstant %[[#F32]] 0x1p+128{{$}}
+; CHECK-DAG: OpConstant %[[#F32]] -0x1p+128{{$}}
+; CHECK-DAG: OpConstant %[[#F32]] 0x1.8p+128{{$}}
define void @main() {
entry:
-
-; CHECK: OpConstant %[[#F32]] 0.5
%f = alloca float, align 4
store float 5.000000e-01, ptr %f, align 4
-
-; CHECK: OpConstant %[[#F64]] 0.5
%d = alloca double, align 8
store double 5.000000e-01, ptr %d, align 8
-
-; CHECK: OpConstant %[[#F32]] 1.0000016166037976e-39
%hexf = alloca float, align 4
store float 0x37D5C73200000000, ptr %hexf, align 4
-
-; CHECK: OpConstant %[[#F32]] 0x1p+128
%inf = alloca float, align 4
store float 0x7FF0000000000000, ptr %inf, align 4
-
-; CHECK: OpConstant %[[#F32]] -0x1p+128
%ninf = alloca float, align 4
store float 0xFFF0000000000000, ptr %ninf, align 4
-
-; CHECK: OpConstant %[[#F32]] 0x1.8p+128
%nan = alloca float, align 4
store float 0x7FF8000000000000, ptr %nan, align 4
-
ret void
}
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/constrained-comparison.ll.bak b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/constrained-comparison.ll.bak
new file mode 100644
index 0000000000000..f0f0957b9b4c4
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/constrained-comparison.ll.bak
@@ -0,0 +1,66 @@
+; Adapted from https://github.com/KhronosGroup/SPIRV-LLVM-Translator/tree/main/test/llvm-intrinsics
+
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpFOrdEqual
+; CHECK: OpFOrdGreaterThan
+; CHECK: OpFOrdGreaterThanEqual
+; CHECK: OpFOrdLessThan
+; CHECK: OpFOrdLessThanEqual
+; CHECK: OpFOrdNotEqual
+; CHECK: OpOrdered
+; CHECK: OpFUnordEqual
+; CHECK: OpFUnordGreaterThan
+; CHECK: OpFUnordGreaterThanEqual
+; CHECK: OpFUnordLessThan
+; CHECK: OpFUnordLessThanEqual
+; CHECK: OpFUnordNotEqual
+; CHECK: OpUnordered
+
+; Function Attrs: norecurse nounwind strictfp
+define dso_local spir_kernel void @test(float %a) local_unnamed_addr #0 !kernel_arg_addr_space !5 !kernel_arg_access_qual !6 !kernel_arg_type !7 !kernel_arg_base_type !7 !kernel_arg_type_qual !8 !kernel_arg_buffer_location !9 {
+entry:
+ %cmp = tail call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %a, metadata !"oeq", metadata !"fpexcept.strict") #2
+ %cmp1 = tail call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %a, metadata !"ogt", metadata !"fpexcept.strict") #2
+ %cmp2 = tail call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %a, metadata !"oge", metadata !"fpexcept.strict") #2
+ %cmp3 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"olt", metadata !"fpexcept.strict") #2
+ %cmp4 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"ole", metadata !"fpexcept.strict") #2
+ %cmp5 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"one", metadata !"fpexcept.strict") #2
+ %cmp6 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"ord", metadata !"fpexcept.strict") #2
+ %cmp7 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"ueq", metadata !"fpexcept.strict") #2
+ %cmp8 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"ugt", metadata !"fpexcept.strict") #2
+ %cmp9 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"uge", metadata !"fpexcept.strict") #2
+ %cmp10 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"ult", metadata !"fpexcept.strict") #2
+ %cmp11 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"ule", metadata !"fpexcept.strict") #2
+ %cmp12 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"une", metadata !"fpexcept.strict") #2
+ %cmp13 = tail call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %a, metadata !"uno", metadata !"fpexcept.strict") #2
+ ret void
+}
+
+; Function Attrs: inaccessiblememonly nounwind willreturn
+declare i1 @llvm.experimental.constrained.fcmps.f32(float, float, metadata, metadata) #1
+
+; Function Attrs: inaccessiblememonly nounwind willreturn
+declare i1 @llvm.experimental.constrained.fcmp.f32(float, float, metadata, metadata) #1
+
+attributes #0 = { norecurse nounwind strictfp "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "sycl-module-id"="test2.cl" "uniform-work-group-size"="true" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { inaccessiblememonly nounwind willreturn }
+attributes #2 = { strictfp }
+
+!llvm.module.flags = !{!0}
+!opencl.ocl.version = !{!1}
+!opencl.spir.version = !{!2, !2}
+!spirv.Source = !{!3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, i32 0}
+!2 = !{i32 1, i32 2}
+!3 = !{i32 4, i32 100000}
+!4 = !{!"clang version 12.0.0 (https://github.com/c199914007/llvm.git f0c85a8adeb49638c01eee1451aa9b35462cbfd5)"}
+!5 = !{i32 0}
+!6 = !{!"none"}
+!7 = !{!"float"}
+!8 = !{!""}
+!9 = !{i32 -1}
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/constrained-convert.ll.bak b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/constrained-convert.ll.bak
new file mode 100644
index 0000000000000..0947c76c124aa
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/constrained-convert.ll.bak
@@ -0,0 +1,77 @@
+; Adapted from https://github.com/KhronosGroup/SPIRV-LLVM-Translator/tree/main/test/llvm-intrinsics
+
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpName %[[#sf:]] "conv"
+; CHECK: OpName %[[#uf:]] "conv1"
+; CHECK: OpName %[[#fs:]] "conv2"
+; CHECK: OpName %[[#fu:]] "conv3"
+; CHECK: OpName %[[#fe:]] "conv4"
+; CHECK: OpName %[[#ft:]] "conv5"
+
+; CHECK-DAG: OpDecorate %[[#sf]] FPRoundingMode 0
+; CHECK-DAG: OpDecorate %[[#uf]] FPRoundingMode 1
+; CHECK-DAG: OpDecorate %[[#ft]] FPRoundingMode 2
+
+; CHECK-NOT: OpDecorate %[[#fs]] FPRoundingMode
+; CHECK-NOT: OpDecorate %[[#fu]] FPRoundingMode
+; CHECK-NOT: OpDecorate %[[#fe]] FPRoundingMode
+
+; CHECK: OpConvertSToF %[[#sf]]
+; CHECK: OpConvertUToF %[[#uf]]
+; CHECK: OpConvertFToS %[[#fs]]
+; CHECK: OpConvertFToU %[[#fu]]
+; CHECK: OpFConvert %[[#fe]]
+; CHECK: OpFConvert %[[#ft]]
+
+; Function Attrs: norecurse nounwind strictfp
+define dso_local spir_kernel void @test(float %a, i32 %in, i32 %ui) local_unnamed_addr #0 !kernel_arg_addr_space !5 !kernel_arg_access_qual !6 !kernel_arg_type !7 !kernel_arg_base_type !7 !kernel_arg_type_qual !8 !kernel_arg_buffer_location !9 {
+entry:
+ %conv = tail call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %in, metadata !"round.tonearest", metadata !"fpexcept.ignore") #2
+ %conv1 = tail call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %ui, metadata !"round.towardzero", metadata !"fpexcept.ignore") #2
+ %conv2 = tail call i32 @llvm.experimental.constrained.fptosi.i32.f32(float %conv1, metadata !"fpexcept.ignore") #2
+ %conv3 = tail call i32 @llvm.experimental.constrained.fptoui.i32.f32(float %conv1, metadata !"fpexcept.ignore") #2
+ %conv4 = tail call double @llvm.experimental.constrained.fpext.f64.f32(float %conv1, metadata !"fpexcept.ignore") #2
+ %conv5 = tail call float @llvm.experimental.constrained.fptrunc.f32.f64(double %conv4, metadata !"round.upward", metadata !"fpexcept.ignore") #2
+ ret void
+}
+
+; Function Attrs: inaccessiblememonly nounwind willreturn
+declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata) #1
+
+; Function Attrs: inaccessiblememonly nounwind willreturn
+declare float @llvm.experimental.constrained.uitofp.f32.i32(i32, metadata, metadata) #1
+
+; Function Attrs: inaccessiblememonly nounwind willreturn
+declare i32 @llvm.experimental.constrained.fptosi.i32.f32(float, metadata) #1
+
+; Function Attrs: inaccessiblememonly nounwind willreturn
+declare i32 @llvm.experimental.constrained.fptoui.i32.f32(float, metadata) #1
+
+; Function Attrs: inaccessiblememonly nounwind willreturn
+declare double @llvm.experimental.constrained.fpext.f64.f32(float, metadata) #1
+
+; Function Attrs: inaccessiblememonly nounwind willreturn
+declare float @llvm.experimental.constrained.fptrunc.f32.f64(double, metadata, metadata) #1
+
+attributes #0 = { norecurse nounwind strictfp "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "sycl-module-id"="test2.cl" "uniform-work-group-size"="true" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { inaccessiblememonly nounwind willreturn }
+attributes #2 = { strictfp }
+
+!llvm.module.flags = !{!0}
+!opencl.ocl.version = !{!1}
+!opencl.spir.version = !{!2, !2}
+!spirv.Source = !{!3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, i32 0}
+!2 = !{i32 1, i32 2}
+!3 = !{i32 4, i32 100000}
+!4 = !{!"clang version 12.0.0 (https://github.com/c199914007/llvm.git f0c85a8adeb49638c01eee1451aa9b35462cbfd5)"}
+!5 = !{i32 0, i32 0, i32 0}
+!6 = !{!"none", !"none", !"none"}
+!7 = !{!"float", !"int", !"uint"}
+!8 = !{!"", !"", !""}
+!9 = !{i32 -1, i32 -1, i32 -1}
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/smul.with.overflow.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/smul.with.overflow.ll
index f839774b4f3e3..845acdf3a0bec 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/smul.with.overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/smul.with.overflow.ll
@@ -8,12 +8,10 @@
; CHECK-DAG: %[[Void:.*]] = OpTypeVoid
; CHECK-DAG: %[[PtrChar:.*]] = OpTypePointer Function %[[Char]]
; CHECK-DAG: %[[StructChar:.*]] = OpTypeStruct %[[Char]] %[[Char]]
-; CHECK-DAG: %[[ZeroChar:.*]] = OpConstant %[[Char]] 0
; CHECK-DAG: %[[NullChar:.*]] = OpConstantNull %[[Char]]
; CHECK-DAG: %[[Int:.*]] = OpTypeInt 32 0
; CHECK-DAG: %[[PtrInt:.*]] = OpTypePointer Function %[[Int]]
; CHECK-DAG: %[[StructInt:.*]] = OpTypeStruct %[[Int]] %[[Int]]
-; CHECK-DAG: %[[ZeroInt:.*]] = OpConstant %[[Int]] 0
; CHECK-DAG: %[[NullInt:.*]] = OpConstantNull %[[Int]]
; CHECK-DAG: %[[Bool:.*]] = OpTypeBool
; CHECK-DAG: %[[V2Bool:.*]] = OpTypeVector %[[Bool]] 2
@@ -31,7 +29,7 @@
; CHECK: %[[Val:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 0
; CHECK: %[[Over:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 1
; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[NullChar]]
-; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[ZeroChar]] %[[Val]]
+; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[NullChar]] %[[Val]]
; CHECK: OpStore %[[Ptr]] %[[Res]] Aligned 1
; CHECK: OpReturn
define dso_local spir_func void @umulo_i8(i8 zeroext %a, i8 zeroext %b, ptr nocapture %c) local_unnamed_addr {
@@ -52,7 +50,7 @@ entry:
; CHECK: %[[Val2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 0
; CHECK: %[[Over2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 1
; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[NullInt]]
-; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[ZeroInt]] %[[Val2]]
+; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[NullInt]] %[[Val2]]
; CHECK: OpStore %[[Ptr2]] %[[Res2]] Aligned 4
; CHECK: OpReturn
define dso_local spir_func void @umulo_i32(i32 %a, i32 %b, ptr nocapture %c) local_unnamed_addr {
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/sqrt.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/sqrt.ll
index 5eec92f978b58..7ad2e2b5b2ec2 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/sqrt.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/sqrt.ll
@@ -5,7 +5,7 @@
; CHECK-DAG: %[[#Double:]] = OpTypeFloat 64
; CHECK-DAG: %[[#Double4:]] = OpTypeVector %[[#Double]] 4
; CHECK-DAG: %[[#FloatArg:]] = OpConstant %[[#Float]]
-; CHECK-DAG: %[[#DoubleArg:]] = OpConstant %[[#Double]]
+; CHECK-DAG: %[[#DoubleArg:]] = OpConstant %[[#Double]] 2.71
; CHECK-DAG: %[[#Double4Arg:]] = OpConstantComposite %[[#Double4]]
;; We need to store sqrt results, otherwise isel does not emit sqrts as dead insts.
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll
index fc3e9b6ab3f89..08e429f36827c 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll
@@ -8,12 +8,10 @@
; CHECK-DAG: %[[Void:.*]] = OpTypeVoid
; CHECK-DAG: %[[PtrChar:.*]] = OpTypePointer Function %[[Char]]
; CHECK-DAG: %[[StructChar:.*]] = OpTypeStruct %[[Char]] %[[Char]]
-; CHECK-DAG: %[[ZeroChar:.*]] = OpConstant %[[Char]] 0
; CHECK-DAG: %[[NullChar:.*]] = OpConstantNull %[[Char]]
; CHECK-DAG: %[[Int:.*]] = OpTypeInt 32 0
; CHECK-DAG: %[[PtrInt:.*]] = OpTypePointer Function %[[Int]]
; CHECK-DAG: %[[StructInt:.*]] = OpTypeStruct %[[Int]] %[[Int]]
-; CHECK-DAG: %[[ZeroInt:.*]] = OpConstant %[[Int]] 0
; CHECK-DAG: %[[NullInt:.*]] = OpConstantNull %[[Int]]
; CHECK-DAG: %[[Bool:.*]] = OpTypeBool
; CHECK-DAG: %[[V2Bool:.*]] = OpTypeVector %[[Bool]] 2
@@ -32,7 +30,7 @@
; CHECK: %[[Val:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 0
; CHECK: %[[Over:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 1
; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[NullChar]]
-; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[ZeroChar]] %[[Val]]
+; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[NullChar]] %[[Val]]
; CHECK: OpStore %[[Ptr]] %[[Res]] Aligned 1
; CHECK: OpReturn
define dso_local spir_func void @umulo_i8(i8 zeroext %a, i8 zeroext %b, ptr nocapture %c) local_unnamed_addr {
@@ -53,7 +51,7 @@ entry:
; CHECK: %[[Val2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 0
; CHECK: %[[Over2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 1
; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[NullInt]]
-; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[ZeroInt]] %[[Val2]]
+; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[NullInt]] %[[Val2]]
; CHECK: OpStore %[[Ptr2]] %[[Res2]] Aligned 4
; CHECK: OpReturn
define dso_local spir_func void @umulo_i32(i32 %a, i32 %b, ptr nocapture %c) local_unnamed_addr {
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/umul.with.overflow.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/umul.with.overflow.ll
index e01489d6995f7..8a66ccda7f9fd 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/umul.with.overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/umul.with.overflow.ll
@@ -8,12 +8,10 @@
; CHECK-DAG: %[[Void:.*]] = OpTypeVoid
; CHECK-DAG: %[[PtrChar:.*]] = OpTypePointer Function %[[Char]]
; CHECK-DAG: %[[StructChar:.*]] = OpTypeStruct %[[Char]] %[[Char]]
-; CHECK-DAG: %[[ZeroChar:.*]] = OpConstant %[[Char]] 0
; CHECK-DAG: %[[NullChar:.*]] = OpConstantNull %[[Char]]
; CHECK-DAG: %[[Int:.*]] = OpTypeInt 32 0
; CHECK-DAG: %[[PtrInt:.*]] = OpTypePointer Function %[[Int]]
; CHECK-DAG: %[[StructInt:.*]] = OpTypeStruct %[[Int]] %[[Int]]
-; CHECK-DAG: %[[ZeroInt:.*]] = OpConstant %[[Int]] 0
; CHECK-DAG: %[[NullInt:.*]] = OpConstantNull %[[Int]]
; CHECK-DAG: %[[Bool:.*]] = OpTypeBool
; CHECK-DAG: %[[V2Bool:.*]] = OpTypeVector %[[Bool]] 2
@@ -31,7 +29,7 @@
; CHECK: %[[Val:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 0
; CHECK: %[[Over:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 1
; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[NullChar]]
-; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[ZeroChar]] %[[Val]]
+; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[NullChar]] %[[Val]]
; CHECK: OpStore %[[Ptr]] %[[Res]] Aligned 1
; CHECK: OpReturn
define dso_local spir_func void @umulo_i8(i8 zeroext %a, i8 zeroext %b, ptr nocapture %c) local_unnamed_addr {
@@ -52,7 +50,7 @@ entry:
; CHECK: %[[Val2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 0
; CHECK: %[[Over2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 1
; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[NullInt]]
-; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[ZeroInt]] %[[Val2]]
+; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[NullInt]] %[[Val2]]
; CHECK: OpStore %[[Ptr2]] %[[Res2]] Aligned 4
; CHECK: OpReturn
define dso_local spir_func void @umulo_i32(i32 %a, i32 %b, ptr nocapture %c) local_unnamed_addr {
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/usub.with.overflow.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/usub.with.overflow.ll
index f7ea655e6529a..eafd34324963b 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/usub.with.overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/usub.with.overflow.ll
@@ -8,12 +8,10 @@
; CHECK-DAG: %[[Void:.*]] = OpTypeVoid
; CHECK-DAG: %[[PtrChar:.*]] = OpTypePointer Function %[[Char]]
; CHECK-DAG: %[[StructChar:.*]] = OpTypeStruct %[[Char]] %[[Char]]
-; CHECK-DAG: %[[ZeroChar:.*]] = OpConstant %[[Char]] 0
; CHECK-DAG: %[[NullChar:.*]] = OpConstantNull %[[Char]]
; CHECK-DAG: %[[Int:.*]] = OpTypeInt 32 0
; CHECK-DAG: %[[PtrInt:.*]] = OpTypePointer Function %[[Int]]
; CHECK-DAG: %[[StructInt:.*]] = OpTypeStruct %[[Int]] %[[Int]]
-; CHECK-DAG: %[[ZeroInt:.*]] = OpConstant %[[Int]] 0
; CHECK-DAG: %[[NullInt:.*]] = OpConstantNull %[[Int]]
; CHECK-DAG: %[[Bool:.*]] = OpTypeBool
; CHECK-DAG: %[[V2Bool:.*]] = OpTypeVector %[[Bool]] 2
@@ -31,7 +29,7 @@
; CHECK: %[[Val:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 0
; CHECK: %[[Over:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 1
; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[NullChar]]
-; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[ZeroChar]] %[[Val]]
+; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[NullChar]] %[[Val]]
; CHECK: OpStore %[[Ptr]] %[[Res]] Aligned 1
; CHECK: OpReturn
define dso_local spir_func void @umulo_i8(i8 zeroext %a, i8 zeroext %b, ptr nocapture %c) local_unnamed_addr {
@@ -52,7 +50,7 @@ entry:
; CHECK: %[[Val2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 0
; CHECK: %[[Over2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 1
; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[NullInt]]
-; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[ZeroInt]] %[[Val2]]
+; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[NullInt]] %[[Val2]]
; CHECK: OpStore %[[Ptr2]] %[[Res2]] Aligned 4
; CHECK: OpReturn
define dso_local spir_func void @umulo_i32(i32 %a, i32 %b, ptr nocapture %c) local_unnamed_addr {
diff --git a/llvm/test/CodeGen/SPIRV/opaque_pointers.ll b/llvm/test/CodeGen/SPIRV/opaque_pointers.ll
index db4d1b130b852..24fe6948c1fcd 100644
--- a/llvm/test/CodeGen/SPIRV/opaque_pointers.ll
+++ b/llvm/test/CodeGen/SPIRV/opaque_pointers.ll
@@ -5,7 +5,7 @@
; CHECK-DAG: %[[#Int64Ty:]] = OpTypeInt 64 0
; CHECK-DAG: %[[#PtrInt64Ty:]] = OpTypePointer Function %[[#Int64Ty]]
; CHECK-DAG: %[[#FTy:]] = OpTypeFunction %[[#Int64Ty]] %[[#PtrInt32Ty]]
-; CHECK-DAG: %[[#Const:]] = OpConstant %[[#Int32Ty]] 0
+; CHECK-DAG: %[[#Const:]] = OpConstantNull %[[#Int32Ty]]
; CHECK: OpFunction %[[#Int64Ty]] None %[[#FTy]]
; CHECK: %[[#Param:]] = OpFunctionParameter %[[#PtrInt32Ty]]
; CHECK: OpStore %[[#Param]] %[[#Const]] Aligned 4
diff --git a/llvm/test/CodeGen/SPIRV/optimizations/add-check-overflow.ll b/llvm/test/CodeGen/SPIRV/optimizations/add-check-overflow.ll
index e04678f802d7c..2db620dab8801 100644
--- a/llvm/test/CodeGen/SPIRV/optimizations/add-check-overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/optimizations/add-check-overflow.ll
@@ -23,9 +23,9 @@
; CHECK-DAG: %[[Char:.*]] = OpTypeInt 8 0
; CHECK-DAG: %[[PtrChar:.*]] = OpTypePointer Generic %[[Char]]
; CHECK-DAG: %[[Bool:.*]] = OpTypeBool
-; CHECK-DAG: %[[Const1:.*]] = OpConstant %[[Int]] 1
-; CHECK-DAG: %[[Zero:.*]] = OpConstant %[[Int]] 0
-; CHECK-DAG: %[[Const42:.*]] = OpConstant %[[Char]] 42
+; CHECK-DAG: %[[Const1:.*]] = OpConstant %[[Int]] 1{{$}}
+; CHECK-DAG: %[[Zero:.*]] = OpConstantNull %[[Int]]
+; CHECK-DAG: %[[Const42:.*]] = OpConstant %[[Char]] 42{{$}}
; CHECK: OpFunction
; CHECK: %[[A:.*]] = OpFunctionParameter %[[Int]]
diff --git a/llvm/test/CodeGen/SPIRV/phi-multiple-preds.ll.bak b/llvm/test/CodeGen/SPIRV/phi-multiple-preds.ll.bak
new file mode 100644
index 0000000000000..5ef5a9af9f48d
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/phi-multiple-preds.ll.bak
@@ -0,0 +1,93 @@
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: OpName %[[#Foo:]] "foo"
+; CHECK: %[[#Foo]] = OpFunction
+; CHECK: OpPhi
+; CHECK-NEXT: OpPhi
+; CHECK-NEXT: OpPhi
+; CHECK-NEXT: OpPhi
+
+target triple = "spir64-unknown-unknown"
+
+define spir_kernel void @foo(i64 noundef %addr, i32 noundef %as, i64 noundef %size, i1 noundef zeroext %is_write, i64 noundef %poisoned_addr, ptr addrspace(2) noundef %file, i32 noundef %line, ptr addrspace(2) noundef %func, i1 noundef zeroext %is_recover) {
+entry:
+ %call = tail call spir_func noundef i64 @_ZN12_GLOBAL__N_111MemToShadowEmj(i64 noundef %poisoned_addr, i32 noundef %as)
+ %0 = inttoptr i64 %call to ptr addrspace(1)
+ %1 = load i8, ptr addrspace(1) %0, align 1
+ %cmp = icmp sgt i8 %1, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ %add.ptr = getelementptr inbounds i8, ptr addrspace(1) %0, i64 1
+ %2 = load i8, ptr addrspace(1) %add.ptr, align 1
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+ %shadow_value.0.in = phi i8 [ %2, %if.then ], [ %1, %entry ]
+ switch i8 %shadow_value.0.in, label %sw.default.i [
+ i8 -127, label %exit
+ i8 -111, label %exit
+ i8 -126, label %sw.bb1.i
+ i8 -110, label %sw.bb1.i
+ i8 -125, label %sw.bb2.i
+ i8 -109, label %sw.bb2.i
+ i8 -15, label %sw.bb3.i
+ i8 -14, label %sw.bb3.i
+ i8 -13, label %sw.bb3.i
+ i8 -124, label %sw.epilog
+ i8 -95, label %sw.bb5.i
+ i8 -123, label %sw.bb6.i
+ ]
+
+sw.bb1.i: ; preds = %if.end, %if.end
+ br label %exit
+
+sw.bb2.i: ; preds = %if.end, %if.end
+ br label %exit
+
+sw.bb3.i: ; preds = %if.end, %if.end, %if.end
+ br label %exit
+
+sw.bb5.i: ; preds = %if.end
+ br label %sw.epilog
+
+sw.bb6.i: ; preds = %if.end
+ br label %sw.epilog
+
+sw.default.i: ; preds = %if.end
+ br label %exit
+
+exit: ; preds = %sw.default.i, %sw.bb3.i, %sw.bb2.i, %sw.bb1.i, %if.end, %if.end
+ %retval.0.i = phi i32 [ 0, %sw.default.i ], [ 5, %sw.bb3.i ], [ 3, %sw.bb2.i ], [ 2, %sw.bb1.i ], [ 1, %if.end ], [ 1, %if.end ]
+ switch i8 %shadow_value.0.in, label %sw.default [
+ i8 -127, label %sw.epilog
+ i8 -126, label %sw.epilog
+ i8 -125, label %sw.epilog
+ i8 -15, label %sw.epilog
+ i8 -14, label %sw.epilog
+ i8 -13, label %sw.epilog
+ i8 -124, label %sw.epilog
+ i8 -95, label %sw.epilog
+ i8 -123, label %sw.epilog
+ i8 -111, label %sw.bb4
+ i8 -110, label %sw.bb4
+ i8 -109, label %sw.bb4
+ ]
+
+sw.bb4: ; preds = %exit, %exit, %exit
+ br label %sw.epilog
+
+sw.default: ; preds = %exit
+ br label %sw.epilog
+
+sw.epilog: ; preds = %sw.default, %sw.bb4, %exit, %exit, %exit, %exit, %exit, %exit, %exit, %exit, %exit, %sw.bb6.i, %sw.bb5.i, %if.end
+ %retval.0.i13 = phi i32 [ %retval.0.i, %sw.default ], [ %retval.0.i, %sw.bb4 ], [ %retval.0.i, %exit ], [ %retval.0.i, %exit ], [ %retval.0.i, %exit ], [ %retval.0.i, %exit ], [ %retval.0.i, %exit ], [ %retval.0.i, %exit ], [ %retval.0.i, %exit ], [ %retval.0.i, %exit ], [ %retval.0.i, %exit ], [ 4, %sw.bb5.i ], [ 7, %sw.bb6.i ], [ 6, %if.end ]
+ %error_type.0 = phi i32 [ 0, %sw.default ], [ 3, %sw.bb4 ], [ 1, %exit ], [ 1, %exit ], [ 1, %exit ], [ 1, %exit ], [ 1, %exit ], [ 1, %exit ], [ 1, %exit ], [ 1, %exit ], [ 1, %exit ], [ 1, %sw.bb5.i ], [ 1, %sw.bb6.i ], [ 1, %if.end ]
+ %conv5 = trunc i64 %size to i32
+ tail call spir_func void @_ZN12_GLOBAL__N_127__asan_internal_report_saveEmjPU3AS2KcjS1_bj25DeviceSanitizerMemoryType24DeviceSanitizerErrorTypeb(i64 noundef %addr, ptr addrspace(2) noundef %file, i32 noundef %line, ptr addrspace(2) noundef %func, i1 noundef zeroext %is_write, i32 noundef %conv5, i32 noundef %retval.0.i13, i32 noundef %error_type.0, i1 noundef zeroext %is_recover)
+ ret void
+}
+
+declare i64 @_ZN12_GLOBAL__N_111MemToShadowEmj(i64 noundef, i32 noundef)
+declare void @_ZN12_GLOBAL__N_127__asan_internal_report_saveEmjPU3AS2KcjS1_bj25DeviceSanitizerMemoryType24DeviceSanitizerErrorTypeb(i64 noundef, ptr addrspace(2) noundef, i32 noundef, ptr addrspace(2) noundef, i1 noundef zeroext, i32 noundef, i32 noundef, i32 noundef, i1 noundef zeroext)
diff --git a/llvm/test/CodeGen/SPIRV/pointers/array-skips-gep.ll b/llvm/test/CodeGen/SPIRV/pointers/array-skips-gep.ll
index 85663d6c3eeda..f5e52930a6614 100644
--- a/llvm/test/CodeGen/SPIRV/pointers/array-skips-gep.ll
+++ b/llvm/test/CodeGen/SPIRV/pointers/array-skips-gep.ll
@@ -2,8 +2,8 @@
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan %s -o - -filetype=obj | spirv-val %}
; CHECK-DAG: %[[#uint_ty:]] = OpTypeInt 32 0
-; CHECK-DAG: %[[#uint_0:]] = OpConstant %[[#uint_ty]] 0
-; CHECK-DAG: %[[#int_10:]] = OpConstant %[[#uint_ty]] 10
+; CHECK-DAG: %[[#uint_0:]] = OpConstantNull %[[#uint_ty]]
+; CHECK-DAG: %[[#int_10:]] = OpConstant %[[#uint_ty]] 10{{$}}
; CHECK-DAG: %[[#array_ty:]] = OpTypeArray %[[#uint_ty]] %[[#int_10]]
; CHECK-DAG: %[[#array_fp:]] = OpTypePointer Function %[[#array_ty]]
; CHECK-DAG: %[[#array_pp:]] = OpTypePointer Private %[[#array_ty]]
diff --git a/llvm/test/CodeGen/SPIRV/pointers/getelementptr-downcast-vector.ll b/llvm/test/CodeGen/SPIRV/pointers/getelementptr-downcast-vector.ll
index d4131fa8a2658..ab5b7bc3d48da 100644
--- a/llvm/test/CodeGen/SPIRV/pointers/getelementptr-downcast-vector.ll
+++ b/llvm/test/CodeGen/SPIRV/pointers/getelementptr-downcast-vector.ll
@@ -4,7 +4,7 @@
; CHECK-DAG: %[[#uint:]] = OpTypeInt 32 0
; CHECK-DAG: %[[#uint_pp:]] = OpTypePointer Private %[[#uint]]
; CHECK-DAG: %[[#uint_fp:]] = OpTypePointer Function %[[#uint]]
-; CHECK-DAG: %[[#uint_0:]] = OpConstant %[[#uint]] 0
+; CHECK-DAG: %[[#uint_0:]] = OpConstantNull %[[#uint]]
; CHECK-DAG: %[[#v2:]] = OpTypeVector %[[#uint]] 2
; CHECK-DAG: %[[#v3:]] = OpTypeVector %[[#uint]] 3
; CHECK-DAG: %[[#v4:]] = OpTypeVector %[[#uint]] 4
diff --git a/llvm/test/CodeGen/SPIRV/pstruct.ll b/llvm/test/CodeGen/SPIRV/pstruct.ll
index fd55e9b69e260..2e939799f7a8e 100644
--- a/llvm/test/CodeGen/SPIRV/pstruct.ll
+++ b/llvm/test/CodeGen/SPIRV/pstruct.ll
@@ -11,9 +11,9 @@
; CHECK-SPIRV: %[[#struct]] = OpTypeStruct %[[#int]] %[[#int]] %[[#int]]
; CHECK-SPIRV: %[[#structP:]] = OpTypePointer Function %[[#struct]]
; CHECK-SPIRV: %[[#structPP:]] = OpTypePointer Function %[[#structP]]
-; CHECK-SPIRV: %[[#zero:]] = OpConstant %[[#int]] 0
-; CHECK-SPIRV: %[[#one:]] = OpConstant %[[#int]] 1
-; CHECK-SPIRV: %[[#two:]] = OpConstant %[[#int]] 2
+; CHECK-SPIRV: %[[#zero:]] = OpConstantNull %[[#int]]
+; CHECK-SPIRV: %[[#one:]] = OpConstant %[[#int]] 1{{$}}
+; CHECK-SPIRV: %[[#two:]] = OpConstant %[[#int]] 2{{$}}
define dso_local spir_func i32 @cmp_func(i8* %p1, i8* %p2) {
entry:
diff --git a/llvm/test/CodeGen/SPIRV/scoped_atomicrmw.ll b/llvm/test/CodeGen/SPIRV/scoped_atomicrmw.ll
index 130db18534832..9863881c31331 100644
--- a/llvm/test/CodeGen/SPIRV/scoped_atomicrmw.ll
+++ b/llvm/test/CodeGen/SPIRV/scoped_atomicrmw.ll
@@ -6,14 +6,14 @@
; CHECK: %[[#Int:]] = OpTypeInt 32 0
; CHECK-DAG: %[[#Float:]] = OpTypeFloat 32
-; CHECK-DAG: %[[#Scope_CrossDevice:]] = OpConstant %[[#Int]] 0
-; CHECK-DAG: %[[#Value:]] = OpConstant %[[#Int]] 42
-; CHECK-DAG: %[[#FPValue:]] = OpConstant %[[#Float]] 42
-; CHECK-DAG: %[[#Scope_Invocation:]] = OpConstant %[[#Int]] 4
-; CHECK-DAG: %[[#MemSem_SeqCst:]] = OpConstant %[[#Int]] 16
-; CHECK-DAG: %[[#Scope_Subgroup:]] = OpConstant %[[#Int]] 3
-; CHECK-DAG: %[[#Scope_Workgroup:]] = OpConstant %[[#Int]] 2
-; CHECK-DAG: %[[#Scope_Device:]] = OpConstant %[[#Int]] 1
+; CHECK-DAG: %[[#Scope_CrossDevice:]] = OpConstantNull %[[#Int]]
+; CHECK-DAG: %[[#Value:]] = OpConstant %[[#Int]] 42{{$}}
+; CHECK-DAG: %[[#FPValue:]] = OpConstant %[[#Float]] 42{{$}}
+; CHECK-DAG: %[[#Scope_Invocation:]] = OpConstant %[[#Int]] 4{{$}}
+; CHECK-DAG: %[[#MemSem_SeqCst:]] = OpConstant %[[#Int]] 16{{$}}
+; CHECK-DAG: %[[#Scope_Subgroup:]] = OpConstant %[[#Int]] 3{{$}}
+; CHECK-DAG: %[[#Scope_Workgroup:]] = OpConstant %[[#Int]] 2{{$}}
+; CHECK-DAG: %[[#Scope_Device:]] = OpConstant %[[#Int]] 1{{$}}
; CHECK-DAG: %[[#PointerType:]] = OpTypePointer CrossWorkgroup %[[#Int]]
; CHECK-DAG: %[[#FPPointerType:]] = OpTypePointer CrossWorkgroup %[[#Float]]
; CHECK-DAG: %[[#Pointer:]] = OpVariable %[[#PointerType]] CrossWorkgroup
diff --git a/llvm/test/CodeGen/SPIRV/sitofp-with-bool.ll b/llvm/test/CodeGen/SPIRV/sitofp-with-bool.ll
index d9145e8d9f0a9..2261778658657 100644
--- a/llvm/test/CodeGen/SPIRV/sitofp-with-bool.ll
+++ b/llvm/test/CodeGen/SPIRV/sitofp-with-bool.ll
@@ -3,7 +3,7 @@
; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32 0
; CHECK-DAG: %[[#float:]] = OpTypeFloat 32
; CHECK-DAG: %[[#bool:]] = OpTypeBool
-; CHECK-DAG: %[[#zero:]] = OpConstant %[[#int_32]] 0
+; CHECK-DAG: %[[#zero:]] = OpConstantNull %[[#int_32]]
; CHECK-DAG: %[[#one:]] = OpConstant %[[#int_32]] 1
; CHECK-DAG: %[[#ptr:]] = OpTypePointer CrossWorkgroup %[[#float]]
diff --git a/llvm/test/CodeGen/SPIRV/struct.ll b/llvm/test/CodeGen/SPIRV/struct.ll
index c3d2694cf929c..39906d582efff 100644
--- a/llvm/test/CodeGen/SPIRV/struct.ll
+++ b/llvm/test/CodeGen/SPIRV/struct.ll
@@ -1,4 +1,5 @@
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
%struct.ST = type { i32, i32, i32 }
@@ -7,10 +8,10 @@
; CHECK-DAG: %[[#struct]] = OpTypeStruct %[[#int]] %[[#int]] %[[#int]]
; CHECK-DAG: %[[#structP:]] = OpTypePointer Function %[[#struct]]
; CHECK-DAG: %[[#intP:]] = OpTypePointer Function %[[#int]]
-; CHECK-DAG: %[[#zero:]] = OpConstant %[[#int]] 0
-; CHECK-DAG: %[[#one:]] = OpConstant %[[#int]] 1
-; CHECK-DAG: %[[#two:]] = OpConstant %[[#int]] 2
-; CHECK-DAG: %[[#three:]] = OpConstant %[[#int]] 3
+; CHECK-DAG: %[[#zero:]] = OpConstantNull %[[#int]]
+; CHECK-DAG: %[[#one:]] = OpConstant %[[#int]] 1{{$}}
+; CHECK-DAG: %[[#two:]] = OpConstant %[[#int]] 2{{$}}
+; CHECK-DAG: %[[#three:]] = OpConstant %[[#int]] 3{{$}}
define dso_local spir_func i32 @func() {
entry:
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/AtomicCompareExchangeExplicit_cl20.ll b/llvm/test/CodeGen/SPIRV/transcoding/AtomicCompareExchangeExplicit_cl20.ll
index cb5bce1375b63..24ef0bf425d21 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/AtomicCompareExchangeExplicit_cl20.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/AtomicCompareExchangeExplicit_cl20.ll
@@ -29,11 +29,11 @@
; CHECK-SPIRV: %[[#int:]] = OpTypeInt 32 0
;; Constants below correspond to the SPIR-V spec
-; CHECK-SPIRV-DAG: %[[#DeviceScope:]] = OpConstant %[[#int]] 1
-; CHECK-SPIRV-DAG: %[[#WorkgroupScope:]] = OpConstant %[[#int]] 2
-; CHECK-SPIRV-DAG: %[[#ReleaseMemSem:]] = OpConstant %[[#int]] 4
-; CHECK-SPIRV-DAG: %[[#RelaxedMemSem:]] = OpConstant %[[#int]] 0
-; CHECK-SPIRV-DAG: %[[#AcqRelMemSem:]] = OpConstant %[[#int]] 8
+; CHECK-SPIRV-DAG: %[[#DeviceScope:]] = OpConstant %[[#int]] 1{{$}}
+; CHECK-SPIRV-DAG: %[[#WorkgroupScope:]] = OpConstant %[[#int]] 2{{$}}
+; CHECK-SPIRV-DAG: %[[#ReleaseMemSem:]] = OpConstant %[[#int]] 4{{$}}
+; CHECK-SPIRV-DAG: %[[#RelaxedMemSem:]] = OpConstantNull %[[#int]]
+; CHECK-SPIRV-DAG: %[[#AcqRelMemSem:]] = OpConstant %[[#int]] 8{{$}}
; CHECK-SPIRV: %[[#]] = OpAtomicCompareExchange %[[#]] %[[#]] %[[#DeviceScope]] %[[#ReleaseMemSem]] %[[#RelaxedMemSem]]
; CHECK-SPIRV: %[[#]] = OpAtomicCompareExchange %[[#]] %[[#]] %[[#WorkgroupScope]] %[[#AcqRelMemSem]] %[[#RelaxedMemSem]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll b/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll
index b63c1c60d0073..788767fd6381c 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll
@@ -4,7 +4,7 @@
; CHECK-SPIRV-DAG: %[[#]] = OpBuildNDRange %[[#]] %[[#GWS:]] %[[#LWS:]] %[[#GWO:]]
; CHECK-SPIRV-DAG: %[[#GWS]] = OpConstant %[[#]] 123
; CHECK-SPIRV-DAG: %[[#LWS]] = OpConstant %[[#]] 456
-; CHECK-SPIRV-DAG: %[[#GWO]] = OpConstant %[[#]] 0
+; CHECK-SPIRV-DAG: %[[#GWO]] = OpConstantNull %[[#]]
%struct.ndrange_t = type { i32, [3 x i32], [3 x i32], [3 x i32] }
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpVectorInsertDynamic_i16.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpVectorInsertDynamic_i16.ll
index 37ab201b81a72..c939f827e2bba 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/OpVectorInsertDynamic_i16.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpVectorInsertDynamic_i16.ll
@@ -11,10 +11,10 @@
; CHECK-DAG: %[[#int32:]] = OpTypeInt 32
; CHECK-DAG: %[[#int16_2:]] = OpTypeVector %[[#int16]] 2
; CHECK-DAG: %[[#undef:]] = OpUndef %[[#int16_2]]
-; CHECK-DAG: %[[#const1:]] = OpConstant %[[#int16]] 4
-; CHECK-DAG: %[[#const2:]] = OpConstant %[[#int16]] 8
-; CHECK-NOT: %[[#idx1:]] = OpConstant %[[#int32]] 0
-; CHECK-NOT: %[[#idx2:]] = OpConstant %[[#int32]] 1
+; CHECK-DAG: %[[#const1:]] = OpConstant %[[#int16]] 4{{$}}
+; CHECK-DAG: %[[#const2:]] = OpConstant %[[#int16]] 8{{$}}
+; CHECK-NOT: %[[#idx1:]] = OpConstantNull %[[#int32]]
+; CHECK-NOT: %[[#idx2:]] = OpConstant %[[#int32]] 1{{$}}
; CHECK: %[[#vec1:]] = OpCompositeInsert %[[#int16_2]] %[[#const1]] %[[#undef]] 0
; CHECK: %[[#vec2:]] = OpCompositeInsert %[[#int16_2]] %[[#const2]] %[[#vec1]] 1
; CHECK: %[[#res]] = OpVectorInsertDynamic %[[#int16_2]] %[[#vec2]] %[[#v]] %[[#index]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/atomic_cmpxchg.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/atomic_cmpxchg.ll
index 417b89eb36f0f..5e1752fadc61e 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/atomic_cmpxchg.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/atomic_cmpxchg.ll
@@ -24,11 +24,11 @@
;; below include a bit more information than original source
;; 0x2 Workgroup
-; CHECK-SPIRV-DAG: %[[#WORKGROUP_SCOPE:]] = OpConstant %[[#UINT]] 2
+; CHECK-SPIRV-DAG: %[[#WORKGROUP_SCOPE:]] = OpConstant %[[#UINT]] 2{{$}}
;; 0x0 Relaxed
;; TODO: do we need CrossWorkgroupMemory here as well?
-; CHECK-SPIRV-DAG: %[[#RELAXED:]] = OpConstant %[[#UINT]] 0
+; CHECK-SPIRV-DAG: %[[#RELAXED:]] = OpConstantNull %[[#UINT]]
; CHECK-SPIRV: %[[#TEST]] = OpFunction %[[#]]
; CHECK-SPIRV: %[[#PTR:]] = OpFunctionParameter %[[#UINT_PTR]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/atomic_legacy.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/atomic_legacy.ll
index 3180b57731d01..d12fbb67f6160 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/atomic_legacy.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/atomic_legacy.ll
@@ -20,10 +20,10 @@
;; a bit more information than original source
;; 0x2 Workgroup
-; CHECK-SPIRV-DAG: %[[#WORKGROUP_SCOPE:]] = OpConstant %[[#UINT]] 2
+; CHECK-SPIRV-DAG: %[[#WORKGROUP_SCOPE:]] = OpConstant %[[#UINT]] 2{{$}}
;; 0x0 Relaxed
-; CHECK-SPIRV-DAG: %[[#RELAXED:]] = OpConstant %[[#UINT]] 0
+; CHECK-SPIRV-DAG: %[[#RELAXED:]] = OpConstantNull %[[#UINT]]
; CHECK-SPIRV: %[[#TEST]] = OpFunction %[[#]]
; CHECK-SPIRV: %[[#PTR:]] = OpFunctionParameter %[[#UINT_PTR]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/atomic_work_item_fence.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/atomic_work_item_fence.ll
index c94c130441854..cdf5e61738b69 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/atomic_work_item_fence.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/atomic_work_item_fence.ll
@@ -37,15 +37,15 @@
;; Scopes [4]:
;; 4 Invocation
-; CHECK-SPIRV-DAG: %[[#SCOPE_INVOCATION:]] = OpConstant %[[#UINT]] 4
+; CHECK-SPIRV-DAG: %[[#SCOPE_INVOCATION:]] = OpConstant %[[#UINT]] 4{{$}}
;; 2 Workgroup
-; CHECK-SPIRV-DAG: %[[#SCOPE_WORK_GROUP:]] = OpConstant %[[#UINT]] 2
+; CHECK-SPIRV-DAG: %[[#SCOPE_WORK_GROUP:]] = OpConstant %[[#UINT]] 2{{$}}
;; 1 Device
-; CHECK-SPIRV-DAG: %[[#SCOPE_DEVICE:]] = OpConstant %[[#UINT]] 1
+; CHECK-SPIRV-DAG: %[[#SCOPE_DEVICE:]] = OpConstant %[[#UINT]] 1{{$}}
;; 0 CrossDevice
-; CHECK-SPIRV-DAG: %[[#SCOPE_CROSS_DEVICE:]] = OpConstant %[[#UINT]] 0
+; CHECK-SPIRV-DAG: %[[#SCOPE_CROSS_DEVICE:]] = OpConstantNull %[[#UINT]]
;; 3 Subgroup
-; CHECK-SPIRV-DAG: %[[#SCOPE_SUBGROUP:]] = OpConstant %[[#UINT]] 3
+; CHECK-SPIRV-DAG: %[[#SCOPE_SUBGROUP:]] = OpConstant %[[#UINT]] 3{{$}}
; CHECK-SPIRV: %[[#TEST_CONST_FLAGS]] = OpFunction %[[#]]
; CHECK-SPIRV: OpMemoryBarrier %[[#SCOPE_INVOCATION]] %[[#LOCAL_RELAXED]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/work_group_barrier.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/work_group_barrier.ll
index 0702fd0c9cb9b..a3c79d554a588 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/work_group_barrier.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/work_group_barrier.ll
@@ -54,15 +54,15 @@
;; Scopes [4]:
;; 2 Workgroup
-; CHECK-SPIRV-DAG: %[[#SCOPE_WORK_GROUP:]] = OpConstant %[[#UINT]] 2
+; CHECK-SPIRV-DAG: %[[#SCOPE_WORK_GROUP:]] = OpConstant %[[#UINT]] 2{{$}}
;; 4 Invocation
-; CHECK-SPIRV-DAG: %[[#SCOPE_INVOCATION:]] = OpConstant %[[#UINT]] 4
+; CHECK-SPIRV-DAG: %[[#SCOPE_INVOCATION:]] = OpConstant %[[#UINT]] 4{{$}}
;; 1 Device
-; CHECK-SPIRV-DAG: %[[#SCOPE_DEVICE:]] = OpConstant %[[#UINT]] 1
+; CHECK-SPIRV-DAG: %[[#SCOPE_DEVICE:]] = OpConstant %[[#UINT]] 1{{$}}
;; 0 CrossDevice
-; CHECK-SPIRV-DAG: %[[#SCOPE_CROSS_DEVICE:]] = OpConstant %[[#UINT]] 0
+; CHECK-SPIRV-DAG: %[[#SCOPE_CROSS_DEVICE:]] = OpConstantNull %[[#UINT]]
;; 3 Subgroup
-; CHECK-SPIRV-DAG: %[[#SCOPE_SUBGROUP:]] = OpConstant %[[#UINT]] 3
+; CHECK-SPIRV-DAG: %[[#SCOPE_SUBGROUP:]] = OpConstant %[[#UINT]] 3{{$}}
; CHECK-SPIRV: %[[#TEST_CONST_FLAGS]] = OpFunction %[[#]]
; CHECK-SPIRV: OpControlBarrier %[[#SCOPE_WORK_GROUP]] %[[#SCOPE_WORK_GROUP]] %[[#LOCAL]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/enqueue_kernel.ll b/llvm/test/CodeGen/SPIRV/transcoding/enqueue_kernel.ll
index d23b0687face5..84626fb3ab9bb 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/enqueue_kernel.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/enqueue_kernel.ll
@@ -4,34 +4,34 @@
; TODO(#60133): Requires updates following opaque pointer migration.
; XFAIL: *
-; CHECK-SPIRV: OpEntryPoint Kernel %[[#BlockKer1:]] "__device_side_enqueue_block_invoke_kernel"
-; CHECK-SPIRV: OpEntryPoint Kernel %[[#BlockKer2:]] "__device_side_enqueue_block_invoke_2_kernel"
-; CHECK-SPIRV: OpEntryPoint Kernel %[[#BlockKer3:]] "__device_side_enqueue_block_invoke_3_kernel"
-; CHECK-SPIRV: OpEntryPoint Kernel %[[#BlockKer4:]] "__device_side_enqueue_block_invoke_4_kernel"
-; CHECK-SPIRV: OpEntryPoint Kernel %[[#BlockKer5:]] "__device_side_enqueue_block_invoke_5_kernel"
-; CHECK-SPIRV: OpName %[[#BlockGlb1:]] "__block_literal_global"
-; CHECK-SPIRV: OpName %[[#BlockGlb2:]] "__block_literal_global.1"
-
-; CHECK-SPIRV: %[[#Int32Ty:]] = OpTypeInt 32
-; CHECK-SPIRV: %[[#Int8Ty:]] = OpTypeInt 8
-; CHECK-SPIRV: %[[#VoidTy:]] = OpTypeVoid
-; CHECK-SPIRV: %[[#Int8PtrGenTy:]] = OpTypePointer Generic %[[#Int8Ty]]
-; CHECK-SPIRV: %[[#EventTy:]] = OpTypeDeviceEvent
-; CHECK-SPIRV: %[[#EventPtrTy:]] = OpTypePointer Generic %[[#EventTy]]
-; CHECK-SPIRV: %[[#Int32LocPtrTy:]] = OpTypePointer Function %[[#Int32Ty]]
-; CHECK-SPIRV: %[[#BlockStructTy:]] = OpTypeStruct
-; CHECK-SPIRV: %[[#BlockStructLocPtrTy:]] = OpTypePointer Function %[[#BlockStructTy]]
-; CHECK-SPIRV: %[[#BlockTy1:]] = OpTypeFunction %[[#VoidTy]] %[[#Int8PtrGenTy]]
-; CHECK-SPIRV: %[[#BlockTy2:]] = OpTypeFunction %[[#VoidTy]] %[[#Int8PtrGenTy]]
-; CHECK-SPIRV: %[[#BlockTy3:]] = OpTypeFunction %[[#VoidTy]] %[[#Int8PtrGenTy]]
-
-; CHECK-SPIRV: %[[#ConstInt0:]] = OpConstant %[[#Int32Ty]] 0
-; CHECK-SPIRV: %[[#EventNull:]] = OpConstantNull %[[#EventPtrTy]]
-; CHECK-SPIRV: %[[#ConstInt21:]] = OpConstant %[[#Int32Ty]] 21
-; CHECK-SPIRV: %[[#ConstInt8:]] = OpConstant %[[#Int32Ty]] 8
-; CHECK-SPIRV: %[[#ConstInt24:]] = OpConstant %[[#Int32Ty]] 24
-; CHECK-SPIRV: %[[#ConstInt12:]] = OpConstant %[[#Int32Ty]] 12
-; CHECK-SPIRV: %[[#ConstInt2:]] = OpConstant %[[#Int32Ty]] 2
+; CHECK-SPIRV-DAG: OpEntryPoint Kernel %[[#BlockKer1:]] "__device_side_enqueue_block_invoke_kernel"
+; CHECK-SPIRV-DAG: OpEntryPoint Kernel %[[#BlockKer2:]] "__device_side_enqueue_block_invoke_2_kernel"
+; CHECK-SPIRV-DAG: OpEntryPoint Kernel %[[#BlockKer3:]] "__device_side_enqueue_block_invoke_3_kernel"
+; CHECK-SPIRV-DAG: OpEntryPoint Kernel %[[#BlockKer4:]] "__device_side_enqueue_block_invoke_4_kernel"
+; CHECK-SPIRV-DAG: OpEntryPoint Kernel %[[#BlockKer5:]] "__device_side_enqueue_block_invoke_5_kernel"
+; CHECK-SPIRV-DAG: OpName %[[#BlockGlb1:]] "__block_literal_global"
+; CHECK-SPIRV-DAG: OpName %[[#BlockGlb2:]] "__block_literal_global.1"
+
+; CHECK-SPIRV-DAG: %[[#Int32Ty:]] = OpTypeInt 32
+; CHECK-SPIRV-DAG: %[[#Int8Ty:]] = OpTypeInt 8
+; CHECK-SPIRV-DAG: %[[#VoidTy:]] = OpTypeVoid
+; CHECK-SPIRV-DAG: %[[#Int8PtrGenTy:]] = OpTypePointer Generic %[[#Int8Ty]]
+; CHECK-SPIRV-DAG: %[[#EventTy:]] = OpTypeDeviceEvent
+; CHECK-SPIRV-DAG: %[[#EventPtrTy:]] = OpTypePointer Generic %[[#EventTy]]
+; CHECK-SPIRV-DAG: %[[#Int32LocPtrTy:]] = OpTypePointer Function %[[#Int32Ty]]
+; CHECK-SPIRV-DAG: %[[#BlockStructTy:]] = OpTypeStruct
+; CHECK-SPIRV-DAG: %[[#BlockStructLocPtrTy:]] = OpTypePointer Function %[[#BlockStructTy]]
+; CHECK-SPIRV-DAG: %[[#BlockTy1:]] = OpTypeFunction %[[#VoidTy]] %[[#Int8PtrGenTy]]
+; CHECK-SPIRV-DAG: %[[#BlockTy2:]] = OpTypeFunction %[[#VoidTy]] %[[#Int8PtrGenTy]]
+; CHECK-SPIRV-DAG: %[[#BlockTy3:]] = OpTypeFunction %[[#VoidTy]] %[[#Int8PtrGenTy]]
+
+; CHECK-SPIRV-DAG: %[[#ConstInt0:]] = OpConstantNull %[[#Int32Ty]]
+; CHECK-SPIRV-DAG: %[[#EventNull:]] = OpConstantNull %[[#EventPtrTy]]
+; CHECK-SPIRV-DAG: %[[#ConstInt21:]] = OpConstant %[[#Int32Ty]] 21{{$}}
+; CHECK-SPIRV-DAG: %[[#ConstInt8:]] = OpConstant %[[#Int32Ty]] 8{{$}}
+; CHECK-SPIRV-DAG: %[[#ConstInt24:]] = OpConstant %[[#Int32Ty]] 24{{$}}
+; CHECK-SPIRV-DAG: %[[#ConstInt12:]] = OpConstant %[[#Int32Ty]] 12{{$}}
+; CHECK-SPIRV-DAG: %[[#ConstInt2:]] = OpConstant %[[#Int32Ty]] 2{{$}}
;; typedef struct {int a;} ndrange_t;
;; #define NULL ((void*)0)
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/group_ops.ll b/llvm/test/CodeGen/SPIRV/transcoding/group_ops.ll
index 870d9b76d5f3e..e654836dbdaf1 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/group_ops.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/group_ops.ll
@@ -8,9 +8,9 @@
; CHECK-SPIRV-DAG: %[[#intv2:]] = OpTypeVector %[[#int]] 2
; CHECK-SPIRV-DAG: %[[#intv3:]] = OpTypeVector %[[#int]] 3
; CHECK-SPIRV-DAG: %[[#float:]] = OpTypeFloat 32
-; CHECK-SPIRV-DAG: %[[#ScopeCrossWorkgroup:]] = OpConstant %[[#int]] 0
-; CHECK-SPIRV-DAG: %[[#ScopeWorkgroup:]] = OpConstant %[[#int]] 2
-; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3
+; CHECK-SPIRV-DAG: %[[#ScopeCrossWorkgroup:]] = OpConstantNull %[[#int]]
+; CHECK-SPIRV-DAG: %[[#ScopeWorkgroup:]] = OpConstant %[[#int]] 2{{$}}
+; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3{{$}}
; CHECK-SPIRV: OpFunction
; CHECK-SPIRV: %[[#]] = OpGroupFMax %[[#float]] %[[#ScopeWorkgroup]] Reduce
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/memcpy-zext.ll b/llvm/test/CodeGen/SPIRV/transcoding/memcpy-zext.ll
index 89fa93b4fcda1..69d471f993206 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/memcpy-zext.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/memcpy-zext.ll
@@ -6,14 +6,14 @@
; CHECK-DAG: %[[#i64:]] = OpTypeInt 64 0
; CHECK-DAG: %[[#i8:]] = OpTypeInt 8 0
; CHECK-DAG: %[[#i32:]] = OpTypeInt 32 0
-; CHECK-DAG: %[[#one:]] = OpConstant %[[#i32]] 1
-; CHECK-DAG: %[[#two:]] = OpConstant %[[#i32]] 2
-; CHECK-DAG: %[[#three:]] = OpConstant %[[#i32]] 3
+; CHECK-DAG: %[[#one:]] = OpConstant %[[#i32]] 1{{$}}
+; CHECK-DAG: %[[#two:]] = OpConstant %[[#i32]] 2{{$}}
+; CHECK-DAG: %[[#three:]] = OpConstant %[[#i32]] 3{{$}}
; CHECK-DAG: %[[#i32x3:]] = OpTypeArray %[[#i32]] %[[#three]]
; CHECK-DAG: %[[#test_arr_init:]] = OpConstantComposite %[[#i32x3]] %[[#one]] %[[#two]] %[[#three]]
-; CHECK-DAG: %[[#szconst1024:]] = OpConstant %[[#i32]] 1024
-; CHECK-DAG: %[[#szconst42:]] = OpConstant %[[#i8]] 42
-; CHECK-DAG: %[[#szconst123:]] = OpConstant %[[#i64]] 123
+; CHECK-DAG: %[[#szconst1024:]] = OpConstant %[[#i32]] 1024{{$}}
+; CHECK-DAG: %[[#szconst42:]] = OpConstant %[[#i8]] 42{{$}}
+; CHECK-DAG: %[[#szconst123:]] = OpConstant %[[#i64]] 123{{$}}
; CHECK-DAG: %[[#const_i32x3_ptr:]] = OpTypePointer UniformConstant %[[#i32x3]]
; CHECK-DAG: %[[#test_arr:]] = OpVariable %[[#const_i32x3_ptr]] UniformConstant %[[#test_arr_init]]
; CHECK-DAG: %[[#i32x3_ptr:]] = OpTypePointer Function %[[#i32x3]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/spirv-private-array-initialization.ll b/llvm/test/CodeGen/SPIRV/transcoding/spirv-private-array-initialization.ll
index 5810d9c59ee3c..710e5c533f9cb 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/spirv-private-array-initialization.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/spirv-private-array-initialization.ll
@@ -6,12 +6,12 @@
; CHECK-SPIRV-64-DAG: %[[#i64:]] = OpTypeInt 64 0
; CHECK-SPIRV-DAG: %[[#i32:]] = OpTypeInt 32 0
-; CHECK-SPIRV-DAG: %[[#one:]] = OpConstant %[[#i32]] 1
-; CHECK-SPIRV-DAG: %[[#two:]] = OpConstant %[[#i32]] 2
-; CHECK-SPIRV-DAG: %[[#three:]] = OpConstant %[[#i32]] 3
+; CHECK-SPIRV-DAG: %[[#one:]] = OpConstant %[[#i32]] 1{{$}}
+; CHECK-SPIRV-DAG: %[[#two:]] = OpConstant %[[#i32]] 2{{$}}
+; CHECK-SPIRV-DAG: %[[#three:]] = OpConstant %[[#i32]] 3{{$}}
; CHECK-SPIRV-DAG: %[[#i32x3:]] = OpTypeArray %[[#i32]] %[[#three]]
; CHECK-SPIRV-DAG: %[[#test_arr_init:]] = OpConstantComposite %[[#i32x3]] %[[#one]] %[[#two]] %[[#three]]
-; CHECK-SPIRV-DAG: %[[#twelve:]] = OpConstant %[[#i32]] 12
+; CHECK-SPIRV-DAG: %[[#twelve:]] = OpConstant %[[#i32]] 12{{$}}
; CHECK-SPIRV-DAG: %[[#const_i32x3_ptr:]] = OpTypePointer UniformConstant %[[#i32x3]]
; CHECK-SPIRV-DAG: %[[#test_arr1:]] = OpVariable %[[#const_i32x3_ptr]] UniformConstant %[[#test_arr_init]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_ballot.ll b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_ballot.ll
index a815f5d44969c..059169eafa97b 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_ballot.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_ballot.ll
@@ -217,14 +217,14 @@
; CHECK-SPIRV-DAG: %[[#double16:]] = OpTypeVector %[[#double]] 16
; CHECK-SPIRV-DAG: %[[#false:]] = OpConstantFalse %[[#bool]]
-; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3
-; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstant %[[#char]] 0
-; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstant %[[#short]] 0
-; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstant %[[#int]] 0
+; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3{{$}}
+; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstantNull %[[#char]]
+; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstantNull %[[#short]]
+; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstantNull %[[#int]]
; CHECK-SPIRV-DAG: %[[#long_0:]] = OpConstantNull %[[#long]]
-; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstant %[[#half]] 0
-; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstant %[[#float]] 0
-; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstant %[[#double]] 0
+; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstantNull %[[#half]]
+; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstantNull %[[#float]]
+; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstantNull %[[#double]]
; CHECK-SPIRV: OpFunction
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformBroadcast %[[#char]] %[[#ScopeSubgroup]] %[[#char_0]] %[[#int_0]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_clustered_reduce.ll b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_clustered_reduce.ll
index 22bf747490da8..ccfd810720a74 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_clustered_reduce.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_clustered_reduce.ll
@@ -187,15 +187,15 @@
; CHECK-SPIRV-DAG: %[[#double:]] = OpTypeFloat 64
; CHECK-SPIRV-DAG: %[[#false:]] = OpConstantFalse %[[#bool]]
-; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3
-; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstant %[[#char]] 0
-; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstant %[[#short]] 0
-; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstant %[[#int]] 0
-; CHECK-SPIRV-DAG: %[[#int_2:]] = OpConstant %[[#int]] 2
+; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3{{$}}
+; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstantNull %[[#char]]
+; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstantNull %[[#short]]
+; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstantNull %[[#int]]
+; CHECK-SPIRV-DAG: %[[#int_2:]] = OpConstant %[[#int]] 2{{$}}
; CHECK-SPIRV-DAG: %[[#long_0:]] = OpConstantNull %[[#long]]
-; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstant %[[#half]] 0
-; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstant %[[#float]] 0
-; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstant %[[#double]] 0
+; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstantNull %[[#half]]
+; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstantNull %[[#float]]
+; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstantNull %[[#double]]
; CHECK-SPIRV: OpFunction
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformIAdd %[[#char]] %[[#ScopeSubgroup]] ClusteredReduce %[[#char_0]] %[[#int_2]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_extended_types.ll b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_extended_types.ll
index 1ba91a2efb6a0..98fac1d28df89 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_extended_types.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_extended_types.ll
@@ -233,13 +233,13 @@
; CHECK-SPIRV-DAG: %[[#double16:]] = OpTypeVector %[[#double]] 16
; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3
-; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstant %[[#char]] 0
-; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstant %[[#short]] 0
-; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstant %[[#int]] 0
+; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstantNull %[[#char]]
+; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstantNull %[[#short]]
+; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstantNull %[[#int]]
; CHECK-SPIRV-DAG: %[[#long_0:]] = OpConstantNull %[[#long]]
-; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstant %[[#half]] 0
-; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstant %[[#float]] 0
-; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstant %[[#double]] 0
+; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstantNull %[[#half]]
+; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstantNull %[[#float]]
+; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstantNull %[[#double]]
; CHECK-SPIRV: OpFunction
; CHECK-SPIRV: %[[#]] = OpGroupBroadcast %[[#char]] %[[#ScopeSubgroup]] %[[#char_0]] %[[#int_0]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_non_uniform_arithmetic.ll b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_non_uniform_arithmetic.ll
index 62b09f6fe6851..3b7e55cdd8263 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_non_uniform_arithmetic.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_non_uniform_arithmetic.ll
@@ -329,16 +329,16 @@
; CHECK-SPIRV-DAG: %[[#double:]] = OpTypeFloat 64
; CHECK-SPIRV-DAG: %[[#false:]] = OpConstantFalse %[[#bool]]
-; CHECK-SPIRV-DAG: %[[#int_32:]] = OpConstant %[[#int]] 32
-; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3
-; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstant %[[#char]] 0
-; CHECK-SPIRV-DAG: %[[#char_10:]] = OpConstant %[[#char]] 10
-; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstant %[[#short]] 0
-; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstant %[[#int]] 0
+; CHECK-SPIRV-DAG: %[[#int_32:]] = OpConstant %[[#int]] 32{{$}}
+; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3{{$}}
+; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstantNull %[[#char]]
+; CHECK-SPIRV-DAG: %[[#char_10:]] = OpConstant %[[#char]] 10{{$}}
+; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstantNull %[[#short]]
+; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstantNull %[[#int]]
; CHECK-SPIRV-DAG: %[[#long_0:]] = OpConstantNull %[[#long]]
-; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstant %[[#half]] 0
-; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstant %[[#float]] 0
-; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstant %[[#double]] 0
+; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstantNull %[[#half]]
+; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstantNull %[[#float]]
+; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstantNull %[[#double]]
; CHECK-SPIRV: OpFunction
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformIAdd %[[#char]] %[[#ScopeSubgroup]] Reduce %[[#char_0]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_non_uniform_vote.ll b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_non_uniform_vote.ll
index 183f1d2eeef59..943f4013fbf93 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_non_uniform_vote.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_non_uniform_vote.ll
@@ -76,15 +76,15 @@
; CHECK-SPIRV-DAG: %[[#false:]] = OpConstantFalse %[[#bool]]
; CHECK-SPIRV-DAG: %[[#true:]] = OpConstantTrue %[[#bool]]
-; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3
-; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstant %[[#char]] 0
-; CHECK-SPIRV-DAG: %[[#char_10:]] = OpConstant %[[#char]] 10
-; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstant %[[#short]] 0
-; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstant %[[#int]] 0
+; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3{{$}}
+; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstantNull %[[#char]]
+; CHECK-SPIRV-DAG: %[[#char_10:]] = OpConstant %[[#char]] 10{{$}}
+; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstantNull %[[#short]]
+; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstantNull %[[#int]]
; CHECK-SPIRV-DAG: %[[#long_0:]] = OpConstantNull %[[#long]]
-; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstant %[[#half]] 0
-; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstant %[[#float]] 0
-; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstant %[[#double]] 0
+; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstantNull %[[#half]]
+; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstantNull %[[#float]]
+; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstantNull %[[#double]]
; CHECK-SPIRV: OpFunction
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformElect %[[#bool]] %[[#ScopeSubgroup]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_shuffle.ll b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_shuffle.ll
index b4099849934a1..013c3030d5568 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_shuffle.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_shuffle.ll
@@ -92,14 +92,14 @@
; CHECK-SPIRV-DAG: %[[#float:]] = OpTypeFloat 32
; CHECK-SPIRV-DAG: %[[#double:]] = OpTypeFloat 64
-; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3
-; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstant %[[#char]] 0
-; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstant %[[#short]] 0
-; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstant %[[#int]] 0
+; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3{{$}}
+; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstantNull %[[#char]]
+; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstantNull %[[#short]]
+; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstantNull %[[#int]]
; CHECK-SPIRV-DAG: %[[#long_0:]] = OpConstantNull %[[#long]]
-; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstant %[[#half]] 0
-; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstant %[[#float]] 0
-; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstant %[[#double]] 0
+; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstantNull %[[#half]]
+; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstantNull %[[#float]]
+; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstantNull %[[#double]]
; CHECK-SPIRV: OpFunction
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformShuffle %[[#char]] %[[#ScopeSubgroup]] %[[#char_0]] %[[#int_0]]
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_shuffle_relative.ll b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_shuffle_relative.ll
index f71d5e42330c9..fe2c7af43c1b6 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/sub_group_shuffle_relative.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/sub_group_shuffle_relative.ll
@@ -92,14 +92,14 @@
; CHECK-SPIRV-DAG: %[[#float:]] = OpTypeFloat 32
; CHECK-SPIRV-DAG: %[[#double:]] = OpTypeFloat 64
-; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3
-; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstant %[[#char]] 0
-; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstant %[[#short]] 0
-; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstant %[[#int]] 0
+; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3{{$}}
+; CHECK-SPIRV-DAG: %[[#char_0:]] = OpConstantNull %[[#char]]
+; CHECK-SPIRV-DAG: %[[#short_0:]] = OpConstantNull %[[#short]]
+; CHECK-SPIRV-DAG: %[[#int_0:]] = OpConstantNull %[[#int]]
; CHECK-SPIRV-DAG: %[[#long_0:]] = OpConstantNull %[[#long]]
-; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstant %[[#half]] 0
-; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstant %[[#float]] 0
-; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstant %[[#double]] 0
+; CHECK-SPIRV-DAG: %[[#half_0:]] = OpConstantNull %[[#half]]
+; CHECK-SPIRV-DAG: %[[#float_0:]] = OpConstantNull %[[#float]]
+; CHECK-SPIRV-DAG: %[[#double_0:]] = OpConstantNull %[[#double]]
; CHECK-SPIRV: OpFunction
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformShuffleUp %[[#char]] %[[#ScopeSubgroup]] %[[#char_0]] %[[#int_0]]
diff --git a/llvm/test/CodeGen/SPIRV/uitofp-with-bool.ll b/llvm/test/CodeGen/SPIRV/uitofp-with-bool.ll
index 6f793fc5d030e..46668645f418b 100644
--- a/llvm/test/CodeGen/SPIRV/uitofp-with-bool.ll
+++ b/llvm/test/CodeGen/SPIRV/uitofp-with-bool.ll
@@ -33,7 +33,7 @@
; SPV-DAG: %[[#int_8:]] = OpTypeInt 8 0
; SPV-DAG: %[[#int_16:]] = OpTypeInt 16 0
; SPV-DAG: %[[#int_64:]] = OpTypeInt 64 0
-; SPV-DAG: %[[#zero_32:]] = OpConstant %[[#int_32]] 0
+; SPV-DAG: %[[#zero_32:]] = OpConstantNull %[[#int_32]]
; SPV-DAG: %[[#one_32:]] = OpConstant %[[#int_32]] 1
; SPV-DAG: %[[#zero_8:]] = OpConstantNull %[[#int_8]]
; SPV-DAG: %[[#mone_8:]] = OpConstant %[[#int_8]] 255
>From 422593ab627398fb1a18c3ac2a688d135aba9986 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 17 Mar 2025 14:07:24 -0700
Subject: [PATCH 11/12] fix test cases
---
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 15 ++++++-----
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 26 ++++++++++---------
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 15 +++++------
llvm/test/CodeGen/SPIRV/keep-tracked-const.ll | 2 +-
.../SPIRV/transcoding/OpenCL/barrier.ll | 18 ++++++-------
5 files changed, 40 insertions(+), 36 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 4f5984d8823ab..f9a64c53ead21 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -1815,20 +1815,23 @@ static bool generateImageSizeQueryInst(const SPIRV::IncomingCall *Call,
// Query result may either be a vector or a scalar. If return type is not a
// vector, expect only a single size component. Otherwise get the number of
// expected components.
- SPIRVType *RetTy = Call->ReturnType;
- unsigned NumExpectedRetComponents = RetTy->getOpcode() == SPIRV::OpTypeVector
- ? RetTy->getOperand(2).getImm()
- : 1;
+ unsigned NumExpectedRetComponents =
+ Call->ReturnType->getOpcode() == SPIRV::OpTypeVector
+ ? Call->ReturnType->getOperand(2).getImm()
+ : 1;
// Get the actual number of query result/size components.
SPIRVType *ImgType = GR->getSPIRVTypeForVReg(Call->Arguments[0]);
unsigned NumActualRetComponents = getNumSizeComponents(ImgType);
Register QueryResult = Call->ReturnRegister;
SPIRVType *QueryResultType = Call->ReturnType;
if (NumExpectedRetComponents != NumActualRetComponents) {
+ unsigned Bitwidth = Call->ReturnType->getOpcode() == SPIRV::OpTypeInt
+ ? Call->ReturnType->getOperand(1).getImm()
+ : 32;
QueryResult = MIRBuilder.getMRI()->createGenericVirtualRegister(
- LLT::fixed_vector(NumActualRetComponents, 32));
+ LLT::fixed_vector(NumActualRetComponents, Bitwidth));
MIRBuilder.getMRI()->setRegClass(QueryResult, &SPIRV::vIDRegClass);
- SPIRVType *IntTy = GR->getOrCreateSPIRVIntegerType(32, MIRBuilder);
+ SPIRVType *IntTy = GR->getOrCreateSPIRVIntegerType(Bitwidth, MIRBuilder);
QueryResultType = GR->getOrCreateSPIRVVectorType(
IntTy, NumActualRetComponents, MIRBuilder, true);
GR->assignSPIRVTypeToVReg(QueryResultType, QueryResult, MIRBuilder.getMF());
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 0198e4d03d63a..79f5f4b80a5e6 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -645,18 +645,20 @@ SPIRVGlobalRegistry::buildConstantSampler(Register ResReg, unsigned AddrMode,
ResReg.isValid()
? ResReg
: MIRBuilder.getMRI()->createVirtualRegister(&SPIRV::iIDRegClass);
- const MachineInstr *NewMI =
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return MIRBuilder.buildInstr(SPIRV::OpConstantSampler)
- .addDef(Sampler)
- .addUse(getSPIRVTypeID(getOrCreateOpTypeSampler(MIRBuilder)))
- .addImm(AddrMode)
- .addImm(Param)
- .addImm(FilerMode);
- });
- // TODO: this is a constant and it needs a usual control flow of add()/find()
- // as other constants
- return NewMI->getOperand(0).getReg();
+ SPIRVType *TypeSampler = getOrCreateOpTypeSampler(MIRBuilder);
+ Register TypeSamplerReg = getSPIRVTypeID(TypeSampler);
+ // We cannot use createOpType() logic here, because of the
+ // GlobalISel/IRTranslator.cpp check for a tail call that expects that
+ // MIRBuilder.getInsertPt() has a previous instruction. If this constant is
+ // inserted as a result of "__translate_sampler_initializer()" this would
+ // break this IRTranslator assumption.
+ MIRBuilder.buildInstr(SPIRV::OpConstantSampler)
+ .addDef(Sampler)
+ .addUse(TypeSamplerReg)
+ .addImm(AddrMode)
+ .addImm(Param)
+ .addImm(FilerMode);
+ return Sampler;
}
Register SPIRVGlobalRegistry::buildGlobalVariable(
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 5addbc5d62d13..6bf663741bf2a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -268,7 +268,8 @@ static void insertBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR,
ToErase.push_back(AssignMI);
MRI->replaceRegWith(Def, Source);
} else {
- GR->assignSPIRVTypeToVReg(AssignedPtrType, Def, MF);
+ if (!GR->getSPIRVTypeForVReg(Def, &MF))
+ GR->assignSPIRVTypeToVReg(AssignedPtrType, Def, MF);
MIB.buildBitcast(Def, Source);
}
}
@@ -442,13 +443,11 @@ void insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpvType,
if (!isTypeFoldingSupported(Def->getOpcode())) {
// No need to generate SPIRV::ASSIGN_TYPE pseudo-instruction
- if (!GR->getSPIRVTypeForVReg(Reg, &MRI.getMF())) {
- if (!MRI.getRegClassOrNull(Reg))
- MRI.setRegClass(Reg, GR->getRegClass(SpvType));
- if (!MRI.getType(Reg).isValid())
- MRI.setType(Reg, GR->getRegType(SpvType));
- GR->assignSPIRVTypeToVReg(SpvType, Reg, MIB.getMF());
- }
+ if (!MRI.getRegClassOrNull(Reg))
+ MRI.setRegClass(Reg, GR->getRegClass(SpvType));
+ if (!MRI.getType(Reg).isValid())
+ MRI.setType(Reg, GR->getRegType(SpvType));
+ GR->assignSPIRVTypeToVReg(SpvType, Reg, MIB.getMF());
return;
}
diff --git a/llvm/test/CodeGen/SPIRV/keep-tracked-const.ll b/llvm/test/CodeGen/SPIRV/keep-tracked-const.ll
index ee3d09e4876af..efde6a2c082fc 100644
--- a/llvm/test/CodeGen/SPIRV/keep-tracked-const.ll
+++ b/llvm/test/CodeGen/SPIRV/keep-tracked-const.ll
@@ -3,7 +3,7 @@
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-; CHECK-SPIRV-DAG: %[[#Int:]] = OpTypeInt 32 0
+; CHECK-SPIRV-DAG: %[[#Int:]] = OpTypeInt 8 0
; CHECK-SPIRV-DAG: %[[#C0:]] = OpConstantNull %[[#Int]]
; CHECK-SPIRV-DAG: %[[#C1:]] = OpConstant %[[#Int]] 1{{$}}
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/barrier.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/barrier.ll
index cf4a24754e7bf..d5612de97a526 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/barrier.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpenCL/barrier.ll
@@ -25,8 +25,8 @@
;; barrier(flags);
;; }
-; CHECK-SPIRV: OpName %[[#TEST_CONST_FLAGS:]] "test_barrier_const_flags"
-; CHECK-SPIRV: %[[#UINT:]] = OpTypeInt 32 0
+; CHECK-SPIRV-DAG: OpName %[[#TEST_CONST_FLAGS:]] "test_barrier_const_flags"
+; CHECK-SPIRV-DAG: %[[#UINT:]] = OpTypeInt 32 0
;; In SPIR-V, barrier is represented as OpControlBarrier [3] and OpenCL
;; cl_mem_fence_flags are represented as part of Memory Semantics [2], which
@@ -35,19 +35,19 @@
;; bit more information than original source
;; 0x10 SequentiallyConsistent + 0x100 WorkgroupMemory
-; CHECK-SPIRV: %[[#LOCAL:]] = OpConstant %[[#UINT]] 272
+; CHECK-SPIRV-DAG: %[[#LOCAL:]] = OpConstant %[[#UINT]] 272{{$}}
;; 0x2 Workgroup
-; CHECK-SPIRV: %[[#WG:]] = OpConstant %[[#UINT]] 2
+; CHECK-SPIRV-DAG: %[[#WG:]] = OpConstant %[[#UINT]] 2{{$}}
;; 0x10 SequentiallyConsistent + 0x200 CrossWorkgroupMemory
-; CHECK-SPIRV-DAG: %[[#GLOBAL:]] = OpConstant %[[#UINT]] 528
+; CHECK-SPIRV-DAG: %[[#GLOBAL:]] = OpConstant %[[#UINT]] 528{{$}}
;; 0x10 SequentiallyConsistent + 0x800 ImageMemory
-; CHECK-SPIRV-DAG: %[[#IMAGE:]] = OpConstant %[[#UINT]] 2064
+; CHECK-SPIRV-DAG: %[[#IMAGE:]] = OpConstant %[[#UINT]] 2064{{$}}
;; 0x10 SequentiallyConsistent + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory
-; CHECK-SPIRV-DAG: %[[#LOCAL_GLOBAL:]] = OpConstant %[[#UINT]] 784
+; CHECK-SPIRV-DAG: %[[#LOCAL_GLOBAL:]] = OpConstant %[[#UINT]] 784{{$}}
;; 0x10 SequentiallyConsistent + 0x100 WorkgroupMemory + 0x800 ImageMemory
-; CHECK-SPIRV-DAG: %[[#LOCAL_IMAGE:]] = OpConstant %[[#UINT]] 2320
+; CHECK-SPIRV-DAG: %[[#LOCAL_IMAGE:]] = OpConstant %[[#UINT]] 2320{{$}}
;; 0x10 SequentiallyConsistent + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory + 0x800 ImageMemory
-; CHECK-SPIRV-DAG: %[[#LOCAL_GLOBAL_IMAGE:]] = OpConstant %[[#UINT]] 2832
+; CHECK-SPIRV-DAG: %[[#LOCAL_GLOBAL_IMAGE:]] = OpConstant %[[#UINT]] 2832{{$}}
; CHECK-SPIRV: %[[#TEST_CONST_FLAGS]] = OpFunction %[[#]]
; CHECK-SPIRV: OpControlBarrier %[[#WG]] %[[#WG]] %[[#LOCAL]]
>From 55e3608ee173c22135f3726ec766c68ede0fa7d6 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 17 Mar 2025 14:22:31 -0700
Subject: [PATCH 12/12] fix test cases
---
.../CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll b/llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll
index cd4d9325c7659..6baac7877a4a8 100644
--- a/llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll
+++ b/llvm/test/CodeGen/SPIRV/passes/translate-aggregate-uaddo.ll
@@ -9,20 +9,20 @@
; Aggregate data are wrapped into @llvm.fake.use(),
; and their attributes are packed into a metadata for @llvm.spv.value.md().
; CHECK-IR: %[[R1:.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32
-; CHECK-IR: call void @llvm.spv.value.md(metadata !0)
+; CHECK-IR: call void @llvm.spv.value.md(metadata !1)
; CHECK-IR: call void (...) @llvm.fake.use({ i32, i1 } %[[R1]])
; CHECK-IR: %math = extractvalue { i32, i1 } %[[R1]], 0
; CHECK-IR: %ov = extractvalue { i32, i1 } %[[R1]], 1
; Type/Name attributes of the value.
-; CHECK-IR: !0 = !{{[{]}}!1, !""{{[}]}}
+; CHECK-IR: !1 = !{{[{]}}!2, !""{{[}]}}
; Origin data type of the value.
-; CHECK-IR: !1 = !{{[{]}}{{[{]}} i32, i1 {{[}]}} poison{{[}]}}
+; CHECK-IR: !2 = !{{[{]}}{{[{]}} i32, i1 {{[}]}} poison{{[}]}}
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -print-after=irtranslator 2>&1 | FileCheck %s --check-prefix=CHECK-GMIR
; Required info succeeded to get through IRTranslator.
; CHECK-GMIR: %[[phires:.*]]:_(s32) = G_PHI
; CHECK-GMIR: %[[math:.*]]:id(s32), %[[ov:.*]]:_(s1) = G_UADDO %[[phires]]:_, %[[#]]:_
-; CHECK-GMIR: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.spv.value.md), !0
+; CHECK-GMIR: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.spv.value.md), !1
; CHECK-GMIR: FAKE_USE %[[math]]:id(s32), %[[ov]]:_(s1)
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -print-after=spirv-prelegalizer 2>&1 | FileCheck %s --check-prefix=CHECK-PRE
More information about the llvm-commits
mailing list