[llvm] 2616c27 - [SPIR-V] Preserve pointer address space for load/gep instructions
Michal Paszkowski via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 19 01:49:46 PDT 2023
Author: Michal Paszkowski
Date: 2023-09-19T01:42:42-07:00
New Revision: 2616c279d5a97a7d9aa7b9972d8dc06dafddc2c7
URL: https://github.com/llvm/llvm-project/commit/2616c279d5a97a7d9aa7b9972d8dc06dafddc2c7
DIFF: https://github.com/llvm/llvm-project/commit/2616c279d5a97a7d9aa7b9972d8dc06dafddc2c7.diff
LOG: [SPIR-V] Preserve pointer address space for load/gep instructions
Differential Revision: https://reviews.llvm.org/D158761
Added:
llvm/test/CodeGen/SPIRV/pointers/getelementptr-addressspace.ll
llvm/test/CodeGen/SPIRV/pointers/load-addressspace.ll
Modified:
llvm/include/llvm/IR/IntrinsicsSPIRV.td
llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 7686ad0bfb009b7..c06f77a05c051e3 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -12,7 +12,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]>;
+ 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_track_constant : Intrinsic<[llvm_any_ty], [llvm_any_ty, llvm_metadata_ty]>;
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 8ef0f9a5a474656..a05e108b8591a37 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -58,11 +58,17 @@ class SPIRVEmitIntrinsics
void preprocessCompositeConstants();
void preprocessUndefs();
CallInst *buildIntrWithMD(Intrinsic::ID IntrID, ArrayRef<Type *> Types,
- Value *Arg, Value *Arg2) {
+ Value *Arg, Value *Arg2,
+ ArrayRef<Constant *> Imms) {
ConstantAsMetadata *CM = ValueAsMetadata::getConstant(Arg);
MDTuple *TyMD = MDNode::get(F->getContext(), CM);
MetadataAsValue *VMD = MetadataAsValue::get(F->getContext(), TyMD);
- return IRB->CreateIntrinsic(IntrID, {Types}, {Arg2, VMD});
+ SmallVector<Value *, 4> Args;
+ Args.push_back(Arg2);
+ Args.push_back(VMD);
+ for (auto *Imm : Imms)
+ Args.push_back(Imm);
+ return IRB->CreateIntrinsic(IntrID, {Types}, Args);
}
void replaceMemInstrUses(Instruction *Old, Instruction *New);
void processInstrAfterVisit(Instruction *I);
@@ -122,6 +128,13 @@ static void setInsertPointSkippingPhis(IRBuilder<> &B, Instruction *I) {
B.SetInsertPoint(I);
}
+static bool requireAssignPtrType(Instruction *I) {
+ if (isa<AllocaInst>(I) || isa<GetElementPtrInst>(I))
+ return true;
+
+ return false;
+}
+
static bool requireAssignType(Instruction *I) {
IntrinsicInst *Intr = dyn_cast<IntrinsicInst>(I);
if (Intr) {
@@ -389,20 +402,30 @@ void SPIRVEmitIntrinsics::processGlobalValue(GlobalVariable &GV) {
}
void SPIRVEmitIntrinsics::insertAssignPtrTypeIntrs(Instruction *I) {
- if (I->getType()->isVoidTy() || !requireAssignType(I))
+ if (I->getType()->isVoidTy() || !requireAssignPtrType(I))
return;
setInsertPointSkippingPhis(*IRB, I->getNextNode());
+
+ Constant *EltTyConst;
+ unsigned AddressSpace = 0;
if (auto *AI = dyn_cast<AllocaInst>(I)) {
- Constant *Const = Constant::getNullValue(AI->getAllocatedType());
- buildIntrWithMD(Intrinsic::spv_assign_ptr_type, {I->getType()}, Const, I);
+ EltTyConst = Constant::getNullValue(AI->getAllocatedType());
+ AddressSpace = AI->getAddressSpace();
+ } else if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
+ EltTyConst = Constant::getNullValue(GEP->getSourceElementType());
+ AddressSpace = GEP->getPointerAddressSpace();
+ } else {
+ llvm_unreachable("Unexpected instruction!");
}
+
+ buildIntrWithMD(Intrinsic::spv_assign_ptr_type, {I->getType()}, EltTyConst, I,
+ {IRB->getInt32(AddressSpace)});
}
void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I) {
Type *Ty = I->getType();
- if (!Ty->isVoidTy() && requireAssignType(I) &&
- I->getOpcode() != Instruction::Alloca) {
+ if (!Ty->isVoidTy() && requireAssignType(I) && !requireAssignPtrType(I)) {
setInsertPointSkippingPhis(*IRB, I->getNextNode());
Type *TypeToAssign = Ty;
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
@@ -414,7 +437,7 @@ void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I) {
}
}
Constant *Const = Constant::getNullValue(TypeToAssign);
- buildIntrWithMD(Intrinsic::spv_assign_type, {Ty}, Const, I);
+ buildIntrWithMD(Intrinsic::spv_assign_type, {Ty}, Const, I, {});
}
for (const auto &Op : I->operands()) {
if (isa<ConstantPointerNull>(Op) || isa<UndefValue>(Op) ||
@@ -423,9 +446,10 @@ void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I) {
setInsertPointSkippingPhis(*IRB, I);
if (isa<UndefValue>(Op) && Op->getType()->isAggregateType())
buildIntrWithMD(Intrinsic::spv_assign_type, {IRB->getInt32Ty()}, Op,
- UndefValue::get(IRB->getInt32Ty()));
+ UndefValue::get(IRB->getInt32Ty()), {});
else
- buildIntrWithMD(Intrinsic::spv_assign_type, {Op->getType()}, Op, Op);
+ buildIntrWithMD(Intrinsic::spv_assign_type, {Op->getType()}, Op, Op,
+ {});
}
}
}
@@ -438,8 +462,8 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I) {
Type *Ty = IRB->getInt32Ty();
auto t = AggrConsts.find(I);
assert(t != AggrConsts.end());
- auto *NewOp =
- buildIntrWithMD(Intrinsic::spv_track_constant, {Ty, Ty}, t->second, I);
+ auto *NewOp = buildIntrWithMD(Intrinsic::spv_track_constant, {Ty, Ty},
+ t->second, I, {});
I->replaceAllUsesWith(NewOp);
NewOp->setArgOperand(0, I);
}
@@ -454,7 +478,7 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I) {
continue;
IRB->SetInsertPoint(I);
auto *NewOp = buildIntrWithMD(Intrinsic::spv_track_constant,
- {Op->getType(), Op->getType()}, Op, Op);
+ {Op->getType(), Op->getType()}, Op, Op, {});
I->setOperand(OpNo, NewOp);
}
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 9a8773e7f5a8d25..f4076be2a7b778f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -248,7 +248,8 @@ static void generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
SPIRVType *BaseTy = GR->getOrCreateSPIRVType(
getMDOperandAsType(MI.getOperand(2).getMetadata(), 0), MIB);
SPIRVType *AssignedPtrType = GR->getOrCreateSPIRVPointerType(
- BaseTy, MI, *MF.getSubtarget<SPIRVSubtarget>().getInstrInfo());
+ BaseTy, MI, *MF.getSubtarget<SPIRVSubtarget>().getInstrInfo(),
+ addressSpaceToStorageClass(MI.getOperand(3).getImm()));
MachineInstr *Def = MRI.getVRegDef(Reg);
assert(Def && "Expecting an instruction that defines the register");
insertAssignInstr(Reg, nullptr, AssignedPtrType, GR, MIB,
diff --git a/llvm/test/CodeGen/SPIRV/pointers/getelementptr-addressspace.ll b/llvm/test/CodeGen/SPIRV/pointers/getelementptr-addressspace.ll
new file mode 100644
index 000000000000000..062863a0e3adc98
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/pointers/getelementptr-addressspace.ll
@@ -0,0 +1,14 @@
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+
+; CHECK: %[[#INT8:]] = OpTypeInt 8 0
+; CHECK: %[[#PTR1:]] = OpTypePointer CrossWorkgroup %[[#INT8]]
+; CHECK: %[[#PTR2:]] = OpTypePointer UniformConstant %[[#INT8]]
+; CHECK: %[[#]] = OpInBoundsPtrAccessChain %[[#PTR1]] %[[#]] %[[#]]
+; CHECK: %[[#]] = OpInBoundsPtrAccessChain %[[#PTR2]] %[[#]] %[[#]]
+
+define spir_kernel void @foo(ptr addrspace(1) %a, ptr addrspace(2) %b) {
+entry:
+ %c = getelementptr inbounds i8, ptr addrspace(1) %a, i32 1
+ %d = getelementptr inbounds i8, ptr addrspace(2) %b, i32 2
+ ret void
+}
diff --git a/llvm/test/CodeGen/SPIRV/pointers/load-addressspace.ll b/llvm/test/CodeGen/SPIRV/pointers/load-addressspace.ll
new file mode 100644
index 000000000000000..1b4e7a3e733fc61
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/pointers/load-addressspace.ll
@@ -0,0 +1,16 @@
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+
+; CHECK: %[[#INT8:]] = OpTypeInt 8 0
+; CHECK: %[[#PTR1:]] = OpTypePointer CrossWorkgroup %[[#INT8]]
+; CHECK: %[[#PTR2:]] = OpTypePointer UniformConstant %[[#INT8]]
+; CHECK: %[[#FNP1:]] = OpFunctionParameter %[[#PTR1]]
+; CHECK: %[[#FNP2:]] = OpFunctionParameter %[[#PTR2]]
+; CHECK: %[[#]] = OpLoad %[[#INT8]] %[[#FNP1]] Aligned 1
+; CHECK: %[[#]] = OpLoad %[[#INT8]] %[[#FNP2]] Aligned 1
+
+define spir_kernel void @foo(ptr addrspace(1) %a, ptr addrspace(2) %b) {
+entry:
+ %c = load i8, ptr addrspace(1) %a
+ %d = load i8, ptr addrspace(2) %b
+ ret void
+}
More information about the llvm-commits
mailing list