-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[SPIR-V] Add validation to the test case with get_image_array_size/get_image_dim calls #94467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SPIR-V] Add validation to the test case with get_image_array_size/get_image_dim calls #94467
Conversation
@llvm/pr-subscribers-backend-spir-v Author: Vyacheslav Levytskyy (VyacheslavLevytskyy) ChangesThis PR is to add validation to the test case with get_image_array_size/get_image_dim calls (transcoding/check_ro_qualifier.ll). This test case didn't pass validation because of invalid emission of OpCompositeExtract instruction (Result Type must be the same type as Composite.). In order to fix the problem this PR improves type inference in general and partially addresses issues:
Full diff: https://github.com/llvm/llvm-project/pull/94467.diff 6 Files Affected:
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 424087f361a6a..9b9b8f7cbc089 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -24,6 +24,13 @@
#define DEBUG_TYPE "spirv-builtins"
namespace llvm {
+
+// Defined in SPIRVPreLegalizer.cpp.
+extern Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
+ SPIRVGlobalRegistry *GR,
+ MachineIRBuilder &MIB,
+ MachineRegisterInfo &MRI);
+
namespace SPIRV {
#define GET_BuiltinGroup_DECL
#include "SPIRVGenTables.inc"
@@ -1451,11 +1458,22 @@ static bool generateImageSizeQueryInst(const SPIRV::IncomingCall *Call,
Component == 3 ? NumActualRetComponents - 1 : Component;
assert(ExtractedComposite < NumActualRetComponents &&
"Invalid composite index!");
+ Register TypeReg = GR->getSPIRVTypeID(Call->ReturnType);
+ SPIRVType *NewType = nullptr;
+ if (QueryResultType->getOpcode() == SPIRV::OpTypeVector) {
+ Register NewTypeReg = QueryResultType->getOperand(1).getReg();
+ if (TypeReg != NewTypeReg &&
+ (NewType = GR->getSPIRVTypeForVReg(NewTypeReg)) != nullptr)
+ TypeReg = NewTypeReg;
+ }
MIRBuilder.buildInstr(SPIRV::OpCompositeExtract)
.addDef(Call->ReturnRegister)
- .addUse(GR->getSPIRVTypeID(Call->ReturnType))
+ .addUse(TypeReg)
.addUse(QueryResult)
.addImm(ExtractedComposite);
+ if (NewType != nullptr)
+ insertAssignInstr(Call->ReturnRegister, nullptr, NewType, GR, MIRBuilder,
+ MIRBuilder.getMF().getRegInfo());
} else {
// More than 1 component is expected, fill a new vector.
auto MIB = MIRBuilder.buildInstr(SPIRV::OpVectorShuffle)
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 5ef0be1cab722..696706258ec40 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -50,6 +50,7 @@ void initializeSPIRVEmitIntrinsicsPass(PassRegistry &);
} // namespace llvm
namespace {
+
class SPIRVEmitIntrinsics
: public ModulePass,
public InstVisitor<SPIRVEmitIntrinsics, Instruction *> {
@@ -61,9 +62,6 @@ class SPIRVEmitIntrinsics
DenseMap<Instruction *, Type *> AggrConstTypes;
DenseSet<Instruction *> AggrStores;
- // a registry of created Intrinsic::spv_assign_ptr_type instructions
- DenseMap<Value *, CallInst *> AssignPtrTypeInstr;
-
// deduce element type of untyped pointers
Type *deduceElementType(Value *I);
Type *deduceElementTypeHelper(Value *I);
@@ -98,14 +96,16 @@ class SPIRVEmitIntrinsics
return B.CreateIntrinsic(IntrID, {Types}, Args);
}
+ void buildAssignType(IRBuilder<> &B, Type *ElemTy, Value *Arg);
void buildAssignPtr(IRBuilder<> &B, Type *ElemTy, Value *Arg);
+ void updateAssignType(CallInst *AssignCI, Value *Arg, Value *OfType);
void replaceMemInstrUses(Instruction *Old, Instruction *New, IRBuilder<> &B);
void processInstrAfterVisit(Instruction *I, IRBuilder<> &B);
void insertAssignPtrTypeIntrs(Instruction *I, IRBuilder<> &B);
void insertAssignTypeIntrs(Instruction *I, IRBuilder<> &B);
- void insertAssignTypeInstrForTargetExtTypes(TargetExtType *AssignedType,
- Value *V, IRBuilder<> &B);
+ void insertAssignPtrTypeTargetExt(TargetExtType *AssignedType, Value *V,
+ IRBuilder<> &B);
void replacePointerOperandWithPtrCast(Instruction *I, Value *Pointer,
Type *ExpectedElementType,
unsigned OperandToReplace,
@@ -218,15 +218,39 @@ static inline void reportFatalOnTokenType(const Instruction *I) {
false);
}
+void SPIRVEmitIntrinsics::buildAssignType(IRBuilder<> &B, Type *Ty,
+ Value *Arg) {
+ Value *OfType = PoisonValue::get(Ty);
+ CallInst *AssignCI = buildIntrWithMD(Intrinsic::spv_assign_type,
+ {Arg->getType()}, OfType, Arg, {}, B);
+ GR->addAssignPtrTypeInstr(Arg, AssignCI);
+}
+
void SPIRVEmitIntrinsics::buildAssignPtr(IRBuilder<> &B, Type *ElemTy,
Value *Arg) {
- CallInst *AssignPtrTyCI =
- buildIntrWithMD(Intrinsic::spv_assign_ptr_type, {Arg->getType()},
- Constant::getNullValue(ElemTy), Arg,
- {B.getInt32(getPointerAddressSpace(Arg->getType()))}, B);
+ Value *OfType = PoisonValue::get(ElemTy);
+ CallInst *AssignPtrTyCI = buildIntrWithMD(
+ Intrinsic::spv_assign_ptr_type, {Arg->getType()}, OfType, Arg,
+ {B.getInt32(getPointerAddressSpace(Arg->getType()))}, B);
GR->addDeducedElementType(AssignPtrTyCI, ElemTy);
GR->addDeducedElementType(Arg, ElemTy);
- AssignPtrTypeInstr[Arg] = AssignPtrTyCI;
+ GR->addAssignPtrTypeInstr(Arg, AssignPtrTyCI);
+}
+
+void SPIRVEmitIntrinsics::updateAssignType(CallInst *AssignCI, Value *Arg,
+ Value *OfType) {
+ LLVMContext &Ctx = Arg->getContext();
+ AssignCI->setArgOperand(
+ 1, MetadataAsValue::get(
+ Ctx, MDNode::get(Ctx, ValueAsMetadata::getConstant(OfType))));
+ if (cast<IntrinsicInst>(AssignCI)->getIntrinsicID() !=
+ Intrinsic::spv_assign_ptr_type)
+ return;
+
+ // update association with the pointee type
+ Type *ElemTy = OfType->getType();
+ GR->addDeducedElementType(AssignCI, ElemTy);
+ GR->addDeducedElementType(Arg, ElemTy);
}
// Set element pointer type to the given value of ValueTy and tries to
@@ -513,19 +537,16 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(Instruction *I) {
if (!Ty) {
GR->addDeducedElementType(Op, KnownElemTy);
// check if there is existing Intrinsic::spv_assign_ptr_type instruction
- auto It = AssignPtrTypeInstr.find(Op);
- if (It == AssignPtrTypeInstr.end()) {
+ CallInst *AssignCI = GR->findAssignPtrTypeInstr(Op);
+ if (AssignCI == nullptr) {
Instruction *User = dyn_cast<Instruction>(Op->use_begin()->get());
setInsertPointSkippingPhis(B, User ? User->getNextNode() : I);
CallInst *CI =
buildIntrWithMD(Intrinsic::spv_assign_ptr_type, {OpTy}, OpTyVal, Op,
{B.getInt32(getPointerAddressSpace(OpTy))}, B);
- AssignPtrTypeInstr[Op] = CI;
+ GR->addAssignPtrTypeInstr(Op, CI);
} else {
- It->second->setArgOperand(
- 1,
- MetadataAsValue::get(
- Ctx, MDNode::get(Ctx, ValueAsMetadata::getConstant(OpTyVal))));
+ updateAssignType(AssignCI, Op, OpTyVal);
}
} else {
if (auto *OpI = dyn_cast<Instruction>(Op)) {
@@ -559,7 +580,9 @@ void SPIRVEmitIntrinsics::replaceMemInstrUses(Instruction *Old,
if (isAssignTypeInstr(U)) {
B.SetInsertPoint(U);
SmallVector<Value *, 2> Args = {New, U->getOperand(1)};
- B.CreateIntrinsic(Intrinsic::spv_assign_type, {New->getType()}, Args);
+ CallInst *AssignCI =
+ B.CreateIntrinsic(Intrinsic::spv_assign_type, {New->getType()}, Args);
+ GR->addAssignPtrTypeInstr(New, AssignCI);
U->eraseFromParent();
} else if (isMemInstrToReplace(U) || isa<ReturnInst>(U) ||
isa<CallInst>(U)) {
@@ -751,33 +774,39 @@ Instruction *SPIRVEmitIntrinsics::visitBitCastInst(BitCastInst &I) {
return NewI;
}
-void SPIRVEmitIntrinsics::insertAssignTypeInstrForTargetExtTypes(
+void SPIRVEmitIntrinsics::insertAssignPtrTypeTargetExt(
TargetExtType *AssignedType, Value *V, IRBuilder<> &B) {
- // Do not emit spv_assign_type if the V is of the AssignedType already.
- if (V->getType() == AssignedType)
- return;
+ Type *VTy = V->getType();
- // Do not emit spv_assign_type if there is one already targetting V. If the
- // found spv_assign_type assigns a type different than AssignedType, report an
- // error. Builtin types cannot be redeclared or casted.
- for (auto User : V->users()) {
- auto *II = dyn_cast<IntrinsicInst>(User);
- if (!II || II->getIntrinsicID() != Intrinsic::spv_assign_type)
- continue;
+ // A couple of sanity checks.
+ assert(isPointerTy(VTy) && "Expect a pointer type!");
+ if (auto PType = dyn_cast<TypedPointerType>(VTy))
+ if (PType->getElementType() != AssignedType)
+ report_fatal_error("Unexpected pointer element type!");
- MetadataAsValue *VMD = cast<MetadataAsValue>(II->getOperand(1));
- Type *BuiltinType =
- dyn_cast<ConstantAsMetadata>(VMD->getMetadata())->getType();
- if (BuiltinType != AssignedType)
- report_fatal_error("Type mismatch " + BuiltinType->getTargetExtName() +
- "/" + AssignedType->getTargetExtName() +
- " for value " + V->getName(),
- false);
+ CallInst *AssignCI = GR->findAssignPtrTypeInstr(V);
+ if (!AssignCI) {
+ buildAssignType(B, AssignedType, V);
return;
}
- Constant *Const = UndefValue::get(AssignedType);
- buildIntrWithMD(Intrinsic::spv_assign_type, {V->getType()}, Const, V, {}, B);
+ Type *CurrentType =
+ dyn_cast<ConstantAsMetadata>(
+ cast<MetadataAsValue>(AssignCI->getOperand(1))->getMetadata())
+ ->getType();
+ if (CurrentType == AssignedType)
+ return;
+
+ // Builtin types cannot be redeclared or casted.
+ if (CurrentType->isTargetExtTy())
+ report_fatal_error("Type mismatch " + CurrentType->getTargetExtName() +
+ "/" + AssignedType->getTargetExtName() +
+ " for value " + V->getName(),
+ false);
+
+ // Our previous guess about the type seems to be wrong, let's update
+ // inferred type according to a new, more precise type information.
+ updateAssignType(AssignCI, V, PoisonValue::get(AssignedType));
}
void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
@@ -850,7 +879,7 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
ExpectedElementTypeConst, Pointer, {B.getInt32(AddressSpace)}, B);
GR->addDeducedElementType(CI, ExpectedElementType);
GR->addDeducedElementType(Pointer, ExpectedElementType);
- AssignPtrTypeInstr[Pointer] = CI;
+ GR->addAssignPtrTypeInstr(Pointer, CI);
return;
}
@@ -929,8 +958,7 @@ void SPIRVEmitIntrinsics::insertPtrCastOrAssignTypeInstr(Instruction *I,
for (unsigned OpIdx = 0; OpIdx < CI->arg_size(); OpIdx++) {
Value *ArgOperand = CI->getArgOperand(OpIdx);
- if (!isa<PointerType>(ArgOperand->getType()) &&
- !isa<TypedPointerType>(ArgOperand->getType()))
+ if (!isPointerTy(ArgOperand->getType()))
continue;
// Constants (nulls/undefs) are handled in insertAssignPtrTypeIntrs()
@@ -952,8 +980,8 @@ void SPIRVEmitIntrinsics::insertPtrCastOrAssignTypeInstr(Instruction *I,
continue;
if (ExpectedType->isTargetExtTy())
- insertAssignTypeInstrForTargetExtTypes(cast<TargetExtType>(ExpectedType),
- ArgOperand, B);
+ insertAssignPtrTypeTargetExt(cast<TargetExtType>(ExpectedType),
+ ArgOperand, B);
else
replacePointerOperandWithPtrCast(CI, ArgOperand, ExpectedType, OpIdx, B);
}
@@ -1145,7 +1173,7 @@ void SPIRVEmitIntrinsics::insertAssignPtrTypeIntrs(Instruction *I,
CallInst *CI = buildIntrWithMD(Intrinsic::spv_assign_ptr_type, {I->getType()},
EltTyConst, I, {B.getInt32(AddressSpace)}, B);
GR->addDeducedElementType(CI, ElemTy);
- AssignPtrTypeInstr[I] = CI;
+ GR->addAssignPtrTypeInstr(I, CI);
}
void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I,
@@ -1164,20 +1192,32 @@ void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I,
TypeToAssign = It->second;
}
}
- Constant *Const = UndefValue::get(TypeToAssign);
- buildIntrWithMD(Intrinsic::spv_assign_type, {Ty}, Const, I, {}, B);
+ buildAssignType(B, TypeToAssign, I);
}
for (const auto &Op : I->operands()) {
if (isa<ConstantPointerNull>(Op) || isa<UndefValue>(Op) ||
// Check GetElementPtrConstantExpr case.
(isa<ConstantExpr>(Op) && isa<GEPOperator>(Op))) {
setInsertPointSkippingPhis(B, I);
- if (isa<UndefValue>(Op) && Op->getType()->isAggregateType())
- buildIntrWithMD(Intrinsic::spv_assign_type, {B.getInt32Ty()}, Op,
- UndefValue::get(B.getInt32Ty()), {}, B);
- else if (!isa<Instruction>(Op))
- buildIntrWithMD(Intrinsic::spv_assign_type, {Op->getType()}, Op, Op, {},
- B);
+ Type *OpTy = Op->getType();
+ if (isa<UndefValue>(Op) && OpTy->isAggregateType()) {
+ CallInst *AssignCI =
+ buildIntrWithMD(Intrinsic::spv_assign_type, {B.getInt32Ty()}, Op,
+ UndefValue::get(B.getInt32Ty()), {}, B);
+ GR->addAssignPtrTypeInstr(Op, AssignCI);
+ } else if (!isa<Instruction>(Op)) {
+ Type *OpTy = Op->getType();
+ if (auto PType = dyn_cast<TypedPointerType>(OpTy)) {
+ buildAssignPtr(B, PType->getElementType(), Op);
+ } else if (isPointerTy(OpTy)) {
+ Type *ElemTy = GR->findDeducedElementType(Op);
+ buildAssignPtr(B, ElemTy ? ElemTy : deduceElementType(Op), Op);
+ } else {
+ CallInst *AssignCI = buildIntrWithMD(Intrinsic::spv_assign_type,
+ {OpTy}, Op, Op, {}, B);
+ GR->addAssignPtrTypeInstr(Op, AssignCI);
+ }
+ }
}
}
}
@@ -1368,14 +1408,12 @@ bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) {
continue;
insertAssignPtrTypeIntrs(I, B);
+ deduceOperandElementType(I);
insertAssignTypeIntrs(I, B);
insertPtrCastOrAssignTypeInstr(I, B);
insertSpirvDecorations(I, B);
}
- for (auto &I : instructions(Func))
- deduceOperandElementType(&I);
-
for (auto *I : Worklist) {
TrackConstants = true;
if (!I->getType()->isVoidTy() || isa<StoreInst>(I))
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 55979ba403a0e..0103fb8214341 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -72,8 +72,11 @@ class SPIRVGlobalRegistry {
// untyped pointers.
DenseMap<Value *, Type *> DeducedElTys;
// Maps composite values to deduced types where untyped pointers are replaced
- // with typed ones
+ // with typed ones.
DenseMap<Value *, Type *> DeducedNestedTys;
+ // Maps values to "assign type" calls, thus being a registry of created
+ // Intrinsic::spv_assign_ptr_type instructions.
+ DenseMap<Value *, CallInst *> AssignPtrTypeInstr;
// Add a new OpTypeXXX instruction without checking for duplicates.
SPIRVType *createSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder,
@@ -148,6 +151,17 @@ class SPIRVGlobalRegistry {
return It == FunResPointerTypes.end() ? nullptr : It->second;
}
+ // A registry of "assign type" records:
+ // - Add a record.
+ void addAssignPtrTypeInstr(Value *Val, CallInst *AssignPtrTyCI) {
+ AssignPtrTypeInstr[Val] = AssignPtrTyCI;
+ }
+ // - Find a record.
+ CallInst *findAssignPtrTypeInstr(const Value *Val) {
+ auto It = AssignPtrTypeInstr.find(Val);
+ return It == AssignPtrTypeInstr.end() ? nullptr : It->second;
+ }
+
// Deduced element types of untyped pointers and composites:
// - Add a record to the map of deduced element types.
void addDeducedElementType(Value *Val, Type *Ty) { DeducedElTys[Val] = Ty; }
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 3d536085b78aa..a0a253c23b1e8 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -417,7 +417,8 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
MachineInstr *Def = MRI.getVRegDef(Reg);
assert(Def && "Expecting an instruction that defines the register");
// G_GLOBAL_VALUE already has type info.
- if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE)
+ if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
+ Def->getOpcode() != SPIRV::ASSIGN_TYPE)
insertAssignInstr(Reg, nullptr, AssignedPtrType, GR, MIB,
MF.getRegInfo());
ToErase.push_back(&MI);
@@ -427,7 +428,8 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
MachineInstr *Def = MRI.getVRegDef(Reg);
assert(Def && "Expecting an instruction that defines the register");
// G_GLOBAL_VALUE already has type info.
- if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE)
+ if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
+ Def->getOpcode() != SPIRV::ASSIGN_TYPE)
insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MF.getRegInfo());
ToErase.push_back(&MI);
} else if (MIOp == TargetOpcode::G_CONSTANT ||
diff --git a/llvm/test/CodeGen/SPIRV/event-wait-ptr-type.ll b/llvm/test/CodeGen/SPIRV/event-wait-ptr-type.ll
index d6fb70bb59a7e..ec9afc789944d 100644
--- a/llvm/test/CodeGen/SPIRV/event-wait-ptr-type.ll
+++ b/llvm/test/CodeGen/SPIRV/event-wait-ptr-type.ll
@@ -4,16 +4,16 @@
; RUN: llc -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: %[[#EventTy:]] = OpTypeEvent
-; CHECK: %[[#StructEventTy:]] = OpTypeStruct %[[#EventTy]]
-; CHECK: %[[#GenPtrStructEventTy:]] = OpTypePointer Generic %[[#StructEventTy]]
-; CHECK: %[[#FunPtrStructEventTy:]] = OpTypePointer Function %[[#StructEventTy]]
-; CHECK: %[[#GenPtrEventTy:]] = OpTypePointer Generic %[[#EventTy:]]
+; CHECK-DAG: %[[#EventTy:]] = OpTypeEvent
+; CHECK-DAG: %[[#StructEventTy:]] = OpTypeStruct %[[#EventTy]]
+; CHECK-DAG: %[[#FunPtrStructEventTy:]] = OpTypePointer Function %[[#StructEventTy]]
+; CHECK-DAG: %[[#GenPtrEventTy:]] = OpTypePointer Generic %[[#EventTy]]
+; CHECK-DAG: %[[#FunPtrEventTy:]] = OpTypePointer Function %[[#EventTy]]
; CHECK: OpFunction
; CHECK: %[[#Var:]] = OpVariable %[[#FunPtrStructEventTy]] Function
-; CHECK-NEXT: %[[#AddrspacecastVar:]] = OpPtrCastToGeneric %[[#GenPtrStructEventTy]] %[[#Var]]
-; CHECK-NEXT: %[[#BitcastVar:]] = OpBitcast %[[#GenPtrEventTy]] %[[#AddrspacecastVar]]
-; CHECK-NEXT: OpGroupWaitEvents %[[#]] %[[#]] %[[#BitcastVar]]
+; CHECK-NEXT: %[[#FunEvent:]] = OpBitcast %[[#FunPtrEventTy]] %[[#Var]]
+; CHECK-NEXT: %[[#GenEvent:]] = OpPtrCastToGeneric %[[#GenPtrEventTy]] %[[#FunEvent]]
+; CHECK-NEXT: OpGroupWaitEvents %[[#]] %[[#]] %[[#GenEvent]]
%"class.sycl::_V1::device_event" = type { target("spirv.Event") }
diff --git a/llvm/test/CodeGen/SPIRV/passes/SPIRVEmitIntrinsics-no-duplicate-spv_assign_type.ll b/llvm/test/CodeGen/SPIRV/passes/SPIRVEmitIntrinsics-no-duplicate-spv_assign_type.ll
index 7056b9cb1230d..9db4f26a27d4f 100644
--- a/llvm/test/CodeGen/SPIRV/passes/SPIRVEmitIntrinsics-no-duplicate-spv_assign_type.ll
+++ b/llvm/test/CodeGen/SPIRV/passes/SPIRVEmitIntrinsics-no-duplicate-spv_assign_type.ll
@@ -3,9 +3,9 @@
; CHECK: *** IR Dump After SPIRV emit intrinsics (emit-intrinsics) ***
define spir_kernel void @test(ptr addrspace(1) %srcimg) {
-; CHECK: call void @llvm.spv.assign.type.p1(ptr addrspace(1) %srcimg, metadata target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 0) undef)
+; CHECK: call void @llvm.spv.assign.type.p1(ptr addrspace(1) %srcimg, metadata target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 0) poison)
%call1 = call spir_func <2 x i32> @_Z13get_image_dim14ocl_image2d_ro(ptr addrspace(1) %srcimg)
-; CHECK-NOT: call void @llvm.spv.assign.type.p1(ptr addrspace(1) %srcimg, metadata target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 0) undef)
+; CHECK-NOT: call void @llvm.spv.assign.type.p1(ptr addrspace(1) %srcimg, metadata target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 0) poison)
%call2 = call spir_func <2 x i32> @_Z13get_image_dim14ocl_image2d_ro(ptr addrspace(1) %srcimg)
ret void
; CHECK: }
|
…en SPIR-V entities and required capability/extensions (#94626) This PR continues #94467 and contains fixes in emission of type intrinsics, constant recording and corresponding test cases: * type-deduce-global-dup.ll -- fix of integer constant emission on 32-bit platforms and correct type deduction for globals * type-deduce-simple-for.ll -- fix of GEP translation (there was an issue previously that led to incorrect translation/broken logic of for-range implementation) This PR also: * fixes a cast between identical storage classes and updates the test case to include validation run by spirv-val, * ensures that Bitcast for pointers satisfies the requirement that the address spaces must match and adds the corresponding test case, * improve encode in Tablegen and decode in code of dependencies between SPIR-V entities and required capability/extensions, * prevent emission of identical OpTypePointer instructions.
…en SPIR-V entities and required capability/extensions (llvm#94626) This PR continues llvm#94467 and contains fixes in emission of type intrinsics, constant recording and corresponding test cases: * type-deduce-global-dup.ll -- fix of integer constant emission on 32-bit platforms and correct type deduction for globals * type-deduce-simple-for.ll -- fix of GEP translation (there was an issue previously that led to incorrect translation/broken logic of for-range implementation) This PR also: * fixes a cast between identical storage classes and updates the test case to include validation run by spirv-val, * ensures that Bitcast for pointers satisfies the requirement that the address spaces must match and adds the corresponding test case, * improve encode in Tablegen and decode in code of dependencies between SPIR-V entities and required capability/extensions, * prevent emission of identical OpTypePointer instructions. Signed-off-by: Hafidz Muzakky <[email protected]>
This PR is to add validation to the test case with get_image_array_size/get_image_dim calls (transcoding/check_ro_qualifier.ll). This test case didn't pass validation because of invalid emission of OpCompositeExtract instruction (Result Type must be the same type as Composite.).
In order to fix the problem this PR improves type inference in general and partially addresses issues:
A reproducer from the description of the latter issue is added as a new test case as a part of this PR.