Skip to content

[SPIR-V] Improve type inference, addrspacecast and dependencies between SPIR-V entities and required capability/extensions #94626

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

Merged
merged 9 commits into from
Jun 7, 2024
19 changes: 6 additions & 13 deletions llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,8 @@ static SPIRVType *getArgSPIRVType(const Function &F, unsigned ArgIdx,
continue;

MetadataAsValue *VMD = cast<MetadataAsValue>(II->getOperand(1));
Type *ElementTy = cast<ConstantAsMetadata>(VMD->getMetadata())->getType();
if (isUntypedPointerTy(ElementTy))
ElementTy =
TypedPointerType::get(IntegerType::getInt8Ty(II->getContext()),
getPointerAddressSpace(ElementTy));
Type *ElementTy =
toTypedPointer(cast<ConstantAsMetadata>(VMD->getMetadata())->getType());
SPIRVType *ElementType = GR->getOrCreateSPIRVType(ElementTy, MIRBuilder);
return GR->getOrCreateSPIRVPointerType(
ElementType, MIRBuilder,
Expand All @@ -257,12 +254,8 @@ static SPIRVType *getArgSPIRVType(const Function &F, unsigned ArgIdx,

// Replace PointerType with TypedPointerType to be able to map SPIR-V types to
// LLVM types in a consistent manner
if (isUntypedPointerTy(OriginalArgType)) {
OriginalArgType =
TypedPointerType::get(Type::getInt8Ty(F.getContext()),
getPointerAddressSpace(OriginalArgType));
}
return GR->getOrCreateSPIRVType(OriginalArgType, MIRBuilder, ArgAccessQual);
return GR->getOrCreateSPIRVType(toTypedPointer(OriginalArgType), MIRBuilder,
ArgAccessQual);
}

static SPIRV::ExecutionModel::ExecutionModel
Expand Down Expand Up @@ -386,8 +379,8 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
Type *FRetTy = FTy->getReturnType();
if (isUntypedPointerTy(FRetTy)) {
if (Type *FRetElemTy = GR->findDeducedElementType(&F)) {
TypedPointerType *DerivedTy =
TypedPointerType::get(FRetElemTy, getPointerAddressSpace(FRetTy));
TypedPointerType *DerivedTy = TypedPointerType::get(
toTypedPointer(FRetElemTy), getPointerAddressSpace(FRetTy));
GR->addReturnType(&F, DerivedTy);
FRetTy = DerivedTy;
}
Expand Down
67 changes: 29 additions & 38 deletions llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ void initializeSPIRVEmitIntrinsicsPass(PassRegistry &);
} // namespace llvm

namespace {

inline MetadataAsValue *buildMD(Value *Arg) {
LLVMContext &Ctx = Arg->getContext();
return MetadataAsValue::get(
Ctx, MDNode::get(Ctx, ValueAsMetadata::getConstant(Arg)));
}

class SPIRVEmitIntrinsics
: public ModulePass,
public InstVisitor<SPIRVEmitIntrinsics, Instruction *> {
Expand Down Expand Up @@ -84,12 +91,9 @@ class SPIRVEmitIntrinsics
CallInst *buildIntrWithMD(Intrinsic::ID IntrID, ArrayRef<Type *> Types,
Value *Arg, Value *Arg2, ArrayRef<Constant *> Imms,
IRBuilder<> &B) {
ConstantAsMetadata *CM = ValueAsMetadata::getConstant(Arg);
MDTuple *TyMD = MDNode::get(F->getContext(), CM);
MetadataAsValue *VMD = MetadataAsValue::get(F->getContext(), TyMD);
SmallVector<Value *, 4> Args;
Args.push_back(Arg2);
Args.push_back(VMD);
Args.push_back(buildMD(Arg));
for (auto *Imm : Imms)
Args.push_back(Imm);
return B.CreateIntrinsic(IntrID, {Types}, Args);
Expand Down Expand Up @@ -228,20 +232,23 @@ void SPIRVEmitIntrinsics::buildAssignType(IRBuilder<> &B, Type *Ty,
void SPIRVEmitIntrinsics::buildAssignPtr(IRBuilder<> &B, Type *ElemTy,
Value *Arg) {
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);
GR->addAssignPtrTypeInstr(Arg, AssignPtrTyCI);
CallInst *AssignPtrTyCI = GR->findAssignPtrTypeInstr(Arg);
if (AssignPtrTyCI == nullptr ||
AssignPtrTyCI->getParent()->getParent() != F) {
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);
GR->addAssignPtrTypeInstr(Arg, AssignPtrTyCI);
} else {
updateAssignType(AssignPtrTyCI, Arg, OfType);
}
}

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))));
AssignCI->setArgOperand(1, buildMD(OfType));
if (cast<IntrinsicInst>(AssignCI)->getIntrinsicID() !=
Intrinsic::spv_assign_ptr_type)
return;
Expand Down Expand Up @@ -560,9 +567,7 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(Instruction *I) {
B.SetInsertPoint(F->getEntryBlock().getFirstNonPHIOrDbgOrAlloca());
}
SmallVector<Type *, 2> Types = {OpTy, OpTy};
MetadataAsValue *VMD = MetadataAsValue::get(
Ctx, MDNode::get(Ctx, ValueAsMetadata::getConstant(OpTyVal)));
SmallVector<Value *, 2> Args = {Op, VMD,
SmallVector<Value *, 2> Args = {Op, buildMD(OpTyVal),
B.getInt32(getPointerAddressSpace(OpTy))};
CallInst *PtrCastI =
B.CreateIntrinsic(Intrinsic::spv_ptrcast, {Types}, Args);
Expand Down Expand Up @@ -689,8 +694,7 @@ Instruction *SPIRVEmitIntrinsics::visitCallInst(CallInst &Call) {
Constant *TyC = UndefValue::get(IA->getFunctionType());
MDString *ConstraintString = MDString::get(Ctx, IA->getConstraintString());
SmallVector<Value *> Args = {
MetadataAsValue::get(Ctx,
MDNode::get(Ctx, ValueAsMetadata::getConstant(TyC))),
buildMD(TyC),
MetadataAsValue::get(Ctx, MDNode::get(Ctx, ConstraintString))};
for (unsigned OpIdx = 0; OpIdx < Call.arg_size(); OpIdx++)
Args.push_back(Call.getArgOperand(OpIdx));
Expand Down Expand Up @@ -822,12 +826,7 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
return;

setInsertPointSkippingPhis(B, I);
Constant *ExpectedElementTypeConst =
Constant::getNullValue(ExpectedElementType);
ConstantAsMetadata *CM =
ValueAsMetadata::getConstant(ExpectedElementTypeConst);
MDTuple *TyMD = MDNode::get(F->getContext(), CM);
MetadataAsValue *VMD = MetadataAsValue::get(F->getContext(), TyMD);
MetadataAsValue *VMD = buildMD(PoisonValue::get(ExpectedElementType));
unsigned AddressSpace = getPointerAddressSpace(Pointer->getType());
bool FirstPtrCastOrAssignPtrType = true;

Expand Down Expand Up @@ -873,12 +872,7 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
// spv_assign_ptr_type instead.
if (FirstPtrCastOrAssignPtrType &&
(isa<Instruction>(Pointer) || isa<Argument>(Pointer))) {
CallInst *CI = buildIntrWithMD(
Intrinsic::spv_assign_ptr_type, {Pointer->getType()},
ExpectedElementTypeConst, Pointer, {B.getInt32(AddressSpace)}, B);
GR->addDeducedElementType(CI, ExpectedElementType);
GR->addDeducedElementType(Pointer, ExpectedElementType);
GR->addAssignPtrTypeInstr(Pointer, CI);
buildAssignPtr(B, ExpectedElementType, Pointer);
return;
}

Expand Down Expand Up @@ -1167,12 +1161,7 @@ void SPIRVEmitIntrinsics::insertAssignPtrTypeIntrs(Instruction *I,

setInsertPointAfterDef(B, I);
Type *ElemTy = deduceElementType(I);
Constant *EltTyConst = UndefValue::get(ElemTy);
unsigned AddressSpace = getPointerAddressSpace(I->getType());
CallInst *CI = buildIntrWithMD(Intrinsic::spv_assign_ptr_type, {I->getType()},
EltTyConst, I, {B.getInt32(AddressSpace)}, B);
GR->addDeducedElementType(CI, ElemTy);
GR->addAssignPtrTypeInstr(I, CI);
buildAssignPtr(B, ElemTy, I);
}

void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I,
Expand Down Expand Up @@ -1407,12 +1396,14 @@ 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))
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,8 +742,7 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeStruct(const StructType *Ty,
bool EmitIR) {
SmallVector<Register, 4> FieldTypes;
for (const auto &Elem : Ty->elements()) {
SPIRVType *ElemTy =
findSPIRVType(toTypedPointer(Elem, Ty->getContext()), MIRBuilder);
SPIRVType *ElemTy = findSPIRVType(toTypedPointer(Elem), MIRBuilder);
assert(ElemTy && ElemTy->getOpcode() != SPIRV::OpTypeVoid &&
"Invalid struct element type");
FieldTypes.push_back(getSPIRVTypeID(ElemTy));
Expand Down
15 changes: 11 additions & 4 deletions llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1086,7 +1086,11 @@ bool SPIRVInstructionSelector::selectAddrSpaceCast(Register ResVReg,

// don't generate a cast between identical storage classes
if (SrcSC == DstSC)
return true;
return BuildMI(*I.getParent(), I, I.getDebugLoc(),
TII.get(TargetOpcode::COPY))
.addDef(ResVReg)
.addUse(SrcPtr)
.constrainAllUses(TII, TRI, RBI);

// Casting from an eligible pointer to Generic.
if (DstSC == SPIRV::StorageClass::Generic && isGenericCastablePtr(SrcSC))
Expand Down Expand Up @@ -1121,10 +1125,13 @@ bool SPIRVInstructionSelector::selectAddrSpaceCast(Register ResVReg,
if (SrcSC == SPIRV::StorageClass::CrossWorkgroup && isUSMStorageClass(DstSC))
return selectUnOp(ResVReg, ResType, I,
SPIRV::OpCrossWorkgroupCastToPtrINTEL);
if (isUSMStorageClass(SrcSC) && DstSC == SPIRV::StorageClass::Generic)
return selectUnOp(ResVReg, ResType, I, SPIRV::OpPtrCastToGeneric);
if (SrcSC == SPIRV::StorageClass::Generic && isUSMStorageClass(DstSC))
return selectUnOp(ResVReg, ResType, I, SPIRV::OpGenericCastToPtr);

// TODO Should this case just be disallowed completely?
// We're casting 2 other arbitrary address spaces, so have to bitcast.
return selectUnOp(ResVReg, ResType, I, SPIRV::OpBitcast);
// Bitcast for pointers requires that the address spaces must match
return false;
}

static unsigned getFCmpOpcode(unsigned PredNum) {
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ getSymbolicOperandRequirements(SPIRV::OperandCategory::OperandCategory Category,
if (ReqCaps.size() == 1) {
auto Cap = ReqCaps[0];
if (Reqs.isCapabilityAvailable(Cap))
return {true, {Cap}, {}, ReqMinVer, ReqMaxVer};
return {true, {Cap}, ReqExts, ReqMinVer, ReqMaxVer};
} else {
// By SPIR-V specification: "If an instruction, enumerant, or other
// feature specifies multiple enabling capabilities, only one such
Expand All @@ -110,7 +110,7 @@ getSymbolicOperandRequirements(SPIRV::OperandCategory::OperandCategory Category,
for (size_t i = 0, Sz = UseCaps.size(); i < Sz; ++i) {
auto Cap = UseCaps[i];
if (i == Sz - 1 || !AvoidCaps.S.contains(Cap))
return {true, {Cap}, {}, ReqMinVer, ReqMaxVer};
return {true, {Cap}, ReqExts, ReqMinVer, ReqMaxVer};
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ static void insertBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR,
}
Register Def = MI.getOperand(0).getReg();
Register Source = MI.getOperand(2).getReg();
SPIRVType *BaseTy = GR->getOrCreateSPIRVType(
getMDOperandAsType(MI.getOperand(3).getMetadata(), 0), MIB);
Type *ElemTy = getMDOperandAsType(MI.getOperand(3).getMetadata(), 0);
SPIRVType *BaseTy = GR->getOrCreateSPIRVType(ElemTy, MIB);
SPIRVType *AssignedPtrType = GR->getOrCreateSPIRVPointerType(
BaseTy, MI, *MF.getSubtarget<SPIRVSubtarget>().getInstrInfo(),
addressSpaceToStorageClass(MI.getOperand(4).getImm(), *ST));
Expand Down Expand Up @@ -220,7 +220,7 @@ static SPIRVType *propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR,
MIB.setInsertPt(*MI->getParent(), MI);
const GlobalValue *Global = MI->getOperand(1).getGlobal();
Type *ElementTy = GR->getDeducedGlobalValueType(Global);
auto *Ty = TypedPointerType::get(ElementTy,
auto *Ty = TypedPointerType::get(toTypedPointer(ElementTy),
Global->getType()->getAddressSpace());
SpirvTy = GR->getOrCreateSPIRVType(Ty, MIB);
break;
Expand Down Expand Up @@ -409,8 +409,8 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
if (isSpvIntrinsic(MI, Intrinsic::spv_assign_ptr_type)) {
Register Reg = MI.getOperand(1).getReg();
MIB.setInsertPt(*MI.getParent(), MI.getIterator());
SPIRVType *BaseTy = GR->getOrCreateSPIRVType(
getMDOperandAsType(MI.getOperand(2).getMetadata(), 0), MIB);
Type *ElementTy = getMDOperandAsType(MI.getOperand(2).getMetadata(), 0);
SPIRVType *BaseTy = GR->getOrCreateSPIRVType(ElementTy, MIB);
SPIRVType *AssignedPtrType = GR->getOrCreateSPIRVPointerType(
BaseTy, MI, *MF.getSubtarget<SPIRVSubtarget>().getInstrInfo(),
addressSpaceToStorageClass(MI.getOperand(3).getImm(), *ST));
Expand Down Expand Up @@ -453,6 +453,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
Ty = TargetExtIt == TargetExtConstTypes.end()
? MI.getOperand(1).getCImm()->getType()
: TargetExtIt->second;
GR->add(MI.getOperand(1).getCImm(), &MF, Reg);
} else if (MIOp == TargetOpcode::G_FCONSTANT) {
Ty = MI.getOperand(1).getFPImm()->getType();
} else {
Expand Down
54 changes: 27 additions & 27 deletions llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
Original file line number Diff line number Diff line change
Expand Up @@ -689,34 +689,34 @@ class StorageClass<string name, bits<32> value> {
bits<32> Value = value;
}

multiclass StorageClassOperand<bits<32> value, list<Capability> reqCapabilities> {
multiclass StorageClassOperand<bits<32> value, list<Extension> reqExtensions, list<Capability> reqCapabilities> {
def : StorageClass<NAME, value>;
defm : SymbolicOperandWithRequirements<StorageClassOperand, value, NAME, 0, 0, [], reqCapabilities>;
}

defm UniformConstant : StorageClassOperand<0, []>;
defm Input : StorageClassOperand<1, []>;
defm Uniform : StorageClassOperand<2, [Shader]>;
defm Output : StorageClassOperand<3, [Shader]>;
defm Workgroup : StorageClassOperand<4, []>;
defm CrossWorkgroup : StorageClassOperand<5, []>;
defm Private : StorageClassOperand<6, [Shader]>;
defm Function : StorageClassOperand<7, []>;
defm Generic : StorageClassOperand<8, [GenericPointer]>;
defm PushConstant : StorageClassOperand<9, [Shader]>;
defm AtomicCounter : StorageClassOperand<10, [AtomicStorage]>;
defm Image : StorageClassOperand<11, []>;
defm StorageBuffer : StorageClassOperand<12, [Shader]>;
defm CallableDataNV : StorageClassOperand<5328, [RayTracingNV]>;
defm IncomingCallableDataNV : StorageClassOperand<5329, [RayTracingNV]>;
defm RayPayloadNV : StorageClassOperand<5338, [RayTracingNV]>;
defm HitAttributeNV : StorageClassOperand<5339, [RayTracingNV]>;
defm IncomingRayPayloadNV : StorageClassOperand<5342, [RayTracingNV]>;
defm ShaderRecordBufferNV : StorageClassOperand<5343, [RayTracingNV]>;
defm PhysicalStorageBufferEXT : StorageClassOperand<5349, [PhysicalStorageBufferAddressesEXT]>;
defm CodeSectionINTEL : StorageClassOperand<5605, [FunctionPointersINTEL]>;
defm DeviceOnlyINTEL : StorageClassOperand<5936, [USMStorageClassesINTEL]>;
defm HostOnlyINTEL : StorageClassOperand<5937, [USMStorageClassesINTEL]>;
defm : SymbolicOperandWithRequirements<StorageClassOperand, value, NAME, 0, 0, reqExtensions, reqCapabilities>;
}

defm UniformConstant : StorageClassOperand<0, [], []>;
defm Input : StorageClassOperand<1, [], []>;
defm Uniform : StorageClassOperand<2, [], [Shader]>;
defm Output : StorageClassOperand<3, [], [Shader]>;
defm Workgroup : StorageClassOperand<4, [], []>;
defm CrossWorkgroup : StorageClassOperand<5, [], []>;
defm Private : StorageClassOperand<6, [], [Shader]>;
defm Function : StorageClassOperand<7, [], []>;
defm Generic : StorageClassOperand<8, [], [GenericPointer]>;
defm PushConstant : StorageClassOperand<9, [], [Shader]>;
defm AtomicCounter : StorageClassOperand<10, [], [AtomicStorage]>;
defm Image : StorageClassOperand<11, [], []>;
defm StorageBuffer : StorageClassOperand<12, [], [Shader]>;
defm CallableDataNV : StorageClassOperand<5328, [], [RayTracingNV]>;
defm IncomingCallableDataNV : StorageClassOperand<5329, [], [RayTracingNV]>;
defm RayPayloadNV : StorageClassOperand<5338, [], [RayTracingNV]>;
defm HitAttributeNV : StorageClassOperand<5339, [], [RayTracingNV]>;
defm IncomingRayPayloadNV : StorageClassOperand<5342, [], [RayTracingNV]>;
defm ShaderRecordBufferNV : StorageClassOperand<5343, [], [RayTracingNV]>;
defm PhysicalStorageBufferEXT : StorageClassOperand<5349, [], [PhysicalStorageBufferAddressesEXT]>;
defm CodeSectionINTEL : StorageClassOperand<5605, [SPV_INTEL_function_pointers], [FunctionPointersINTEL]>;
defm DeviceOnlyINTEL : StorageClassOperand<5936, [SPV_INTEL_usm_storage_classes], [USMStorageClassesINTEL]>;
defm HostOnlyINTEL : StorageClassOperand<5937, [SPV_INTEL_usm_storage_classes], [USMStorageClassesINTEL]>;

//===----------------------------------------------------------------------===//
// Multiclass used to define Dim enum values and at the same time
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/SPIRV/SPIRVUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID) {

Type *getMDOperandAsType(const MDNode *N, unsigned I) {
Type *ElementTy = cast<ValueAsMetadata>(N->getOperand(I))->getType();
return toTypedPointer(ElementTy, N->getContext());
return toTypedPointer(ElementTy);
}

// The set of names is borrowed from the SPIR-V translator.
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Target/SPIRV/SPIRVUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ inline bool isTypedPointerTy(const Type *T) {

// True if this is an instance of PointerType.
inline bool isUntypedPointerTy(const Type *T) {
return T->getTypeID() == Type::PointerTyID;
return T && T->getTypeID() == Type::PointerTyID;
}

// True if this is an instance of PointerType or TypedPointerType.
Expand Down Expand Up @@ -153,9 +153,9 @@ inline Type *reconstructFunctionType(Function *F) {
return FunctionType::get(F->getReturnType(), ArgTys, F->isVarArg());
}

inline Type *toTypedPointer(Type *Ty, LLVMContext &Ctx) {
inline Type *toTypedPointer(Type *Ty) {
return isUntypedPointerTy(Ty)
? TypedPointerType::get(IntegerType::getInt8Ty(Ctx),
? TypedPointerType::get(IntegerType::getInt8Ty(Ty->getContext()),
getPointerAddressSpace(Ty))
: Ty;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
; Modified from: https://github.com/KhronosGroup/SPIRV-LLVM-Translator/test/extensions/INTEL/SPV_INTEL_usm_storage_classes/intel_usm_addrspaces.ll

; RUN: llc -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_INTEL_usm_storage_classes %s -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-EXT
; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_usm_storage_classes %s -o - -filetype=obj | spirv-val %}
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_usm_storage_classes %s -o - -filetype=obj | spirv-val %}
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-WITHOUT
; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}

; CHECK-: Capability USMStorageClassesINTEL
; CHECK-SPIRV-WITHOUT-NO: Capability USMStorageClassesINTEL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

define spir_kernel void @test_pointer_cast(ptr addrspace(1) %src) {
; CHECK-NOT: call{{.*}} void @llvm.spv.assign.ptr.type.p1(ptr addrspace(1) %src, metadata i8 undef, i32 1)
; CHECK: call{{.*}} void @llvm.spv.assign.ptr.type.p1(ptr addrspace(1) %src, metadata i32 0, i32 1)
; CHECK: call{{.*}} void @llvm.spv.assign.ptr.type.p1(ptr addrspace(1) %src, metadata i32 poison, i32 1)
%b = bitcast ptr addrspace(1) %src to ptr addrspace(1)
%g = getelementptr inbounds i32, ptr addrspace(1) %b, i64 52
ret void
Expand Down
Loading
Loading