Skip to content

Commit c513ce4

Browse files
Fznamznonvmaksimo
authored andcommitted
Fix SPIR-V friendly IR for OpGenericCastToPtr instruction (intel#1019)
* Fix SPIR-V friendly IR for OpGenericCastToPtr instruction This instruction was translated directly to OCL even if SPIR-V friendly LLVM IR was requested. Original commit: KhronosGroup/SPIRV-LLVM-Translator@76c76ef
1 parent 158c7e2 commit c513ce4

File tree

6 files changed

+69
-28
lines changed

6 files changed

+69
-28
lines changed

llvm-spirv/lib/SPIRV/SPIRVInternal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,9 @@ const static char TranslateSPIRVMemFence[] = "__translate_spirv_memory_fence";
363363
} // namespace kSPIRVName
364364

365365
namespace kSPIRVPostfix {
366+
const static char ToGlobal[] = "ToGlobal";
367+
const static char ToLocal[] = "ToLocal";
368+
const static char ToPrivate[] = "ToPrivate";
366369
const static char Sat[] = "sat";
367370
const static char Rtz[] = "rtz";
368371
const static char Rte[] = "rte";

llvm-spirv/lib/SPIRV/SPIRVReader.cpp

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,8 @@ bool SPIRVToLLVM::isDirectlyTranslatedToOCL(Op OpCode) const {
694694
return true;
695695
if (OpCode == OpImageSampleExplicitLod || OpCode == OpSampledImage)
696696
return false;
697+
if (OpCode == OpGenericCastToPtrExplicit)
698+
return false;
697699
if (isEventOpCode(OpCode))
698700
return false;
699701
if (OCLSPIRVBuiltinMap::rfind(OpCode, nullptr)) {
@@ -2671,7 +2673,7 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
26712673
BV, transOCLBuiltinFromInst(static_cast<SPIRVInstruction *>(BV), BB));
26722674
} else if (isBinaryShiftLogicalBitwiseOpCode(OC) || isLogicalOpCode(OC)) {
26732675
return mapValue(BV, transShiftLogicalBitwiseInst(BV, BB, F));
2674-
} else if (isCvtOpCode(OC)) {
2676+
} else if (isCvtOpCode(OC) && OC != OpGenericCastToPtrExplicit) {
26752677
auto BI = static_cast<SPIRVInstruction *>(BV);
26762678
Value *Inst = nullptr;
26772679
if (BI->hasFPRoundingMode() || BI->isSaturatedConversion())
@@ -3010,9 +3012,7 @@ void SPIRVToLLVM::transOCLBuiltinFromInstPreproc(
30103012
BT->getVectorComponentCount());
30113013
else
30123014
llvm_unreachable("invalid compare instruction");
3013-
} else if (OC == OpGenericCastToPtrExplicit)
3014-
Args.pop_back();
3015-
else if (OC == OpImageRead && Args.size() > 2) {
3015+
} else if (OC == OpImageRead && Args.size() > 2) {
30163016
// Drop "Image operands" argument
30173017
Args.erase(Args.begin() + 2);
30183018
} else if (isSubgroupAvcINTELEvaluateOpcode(OC)) {
@@ -3322,8 +3322,6 @@ SPIRVToLLVM::SPIRVToLLVM(Module *LLVMModule, SPIRVModule *TheSPIRVModule)
33223322

33233323
std::string SPIRVToLLVM::getOCLBuiltinName(SPIRVInstruction *BI) {
33243324
auto OC = BI->getOpCode();
3325-
if (OC == OpGenericCastToPtrExplicit)
3326-
return getOCLGenericCastToPtrName(BI);
33273325
if (OC == OpBuildNDRange) {
33283326
auto NDRangeInst = static_cast<SPIRVBuildNDRange *>(BI);
33293327
auto EleTy = ((NDRangeInst->getOperands())[0])->getType();
@@ -3430,6 +3428,23 @@ std::string getSPIRVFuncSuffix(SPIRVInstruction *BI) {
34303428
Suffix += kSPIRVPostfix::Divider;
34313429
Suffix += SPIRSPIRVFPRoundingModeMap::rmap(Kind);
34323430
}
3431+
if (BI->getOpCode() == OpGenericCastToPtrExplicit) {
3432+
Suffix += kSPIRVPostfix::Divider;
3433+
auto GenericCastToPtrInst = BI->getType()->getPointerStorageClass();
3434+
switch (GenericCastToPtrInst) {
3435+
case StorageClassCrossWorkgroup:
3436+
Suffix += std::string(kSPIRVPostfix::ToGlobal);
3437+
break;
3438+
case StorageClassWorkgroup:
3439+
Suffix += std::string(kSPIRVPostfix::ToLocal);
3440+
break;
3441+
case StorageClassFunction:
3442+
Suffix += std::string(kSPIRVPostfix::ToPrivate);
3443+
break;
3444+
default:
3445+
llvm_unreachable("Invalid address space");
3446+
}
3447+
}
34333448
return Suffix;
34343449
}
34353450

@@ -3442,7 +3457,7 @@ Instruction *SPIRVToLLVM::transSPIRVBuiltinFromInst(SPIRVInstruction *BI,
34423457
AddRetTypePostfix = true;
34433458

34443459
bool IsRetSigned = false;
3445-
if (isCvtOpCode(OC)) {
3460+
if (isCvtOpCode(OC) && OC != OpGenericCastToPtrExplicit) {
34463461
AddRetTypePostfix = true;
34473462
if (OC == OpConvertUToF || OC == OpSatConvertUToS)
34483463
IsRetSigned = true;
@@ -4420,22 +4435,6 @@ bool SPIRVToLLVM::transSourceExtension() {
44204435
return true;
44214436
}
44224437

4423-
// Check Address Space of the Pointer Type
4424-
std::string SPIRVToLLVM::getOCLGenericCastToPtrName(SPIRVInstruction *BI) {
4425-
auto GenericCastToPtrInst = BI->getType()->getPointerStorageClass();
4426-
switch (GenericCastToPtrInst) {
4427-
case StorageClassCrossWorkgroup:
4428-
return std::string(kOCLBuiltinName::ToGlobal);
4429-
case StorageClassWorkgroup:
4430-
return std::string(kOCLBuiltinName::ToLocal);
4431-
case StorageClassFunction:
4432-
return std::string(kOCLBuiltinName::ToPrivate);
4433-
default:
4434-
llvm_unreachable("Invalid address space");
4435-
return "";
4436-
}
4437-
}
4438-
44394438
llvm::GlobalValue::LinkageTypes
44404439
SPIRVToLLVM::transLinkageType(const SPIRVValue *V) {
44414440
int LT = V->getLinkageType();

llvm-spirv/lib/SPIRV/SPIRVReader.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ class SPIRVToLLVM {
7979

8080
static const StringSet<> BuiltInConstFunc;
8181
std::string getOCLBuiltinName(SPIRVInstruction *BI);
82-
std::string getOCLGenericCastToPtrName(SPIRVInstruction *BI);
8382

8483
Type *transType(SPIRVType *BT, bool IsClassMember = false);
8584
std::string transTypeToOCLTypeName(SPIRVType *BT, bool IsSigned = true);

llvm-spirv/lib/SPIRV/SPIRVToOCL.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ void SPIRVToOCLBase::visitCallInst(CallInst &CI) {
115115
visitCallSPIRVImageMediaBlockBuiltin(&CI, OC);
116116
return;
117117
}
118+
if (OC == OpGenericCastToPtrExplicit) {
119+
visitCallGenericCastToPtrExplicitBuiltIn(&CI, OC);
120+
return;
121+
}
118122
if (isCvtOpCode(OC)) {
119123
visitCallSPIRVCvtBuiltin(&CI, OC, DemangledName);
120124
return;
@@ -541,6 +545,32 @@ void SPIRVToOCLBase::visitCallSPIRVImageMediaBlockBuiltin(CallInst *CI, Op OC) {
541545
&Attrs);
542546
}
543547

548+
void SPIRVToOCLBase::visitCallGenericCastToPtrExplicitBuiltIn(CallInst *CI,
549+
Op OC) {
550+
AttributeList Attrs = CI->getCalledFunction()->getAttributes();
551+
mutateCallInstOCL(
552+
M, CI,
553+
[=](CallInst *Call, std::vector<Value *> &Args) {
554+
auto AddrSpace = static_cast<SPIRAddressSpace>(
555+
CI->getType()->getPointerAddressSpace());
556+
// The instruction has two arguments, whereas ocl built-in has only one
557+
// argument.
558+
Args.pop_back();
559+
switch (AddrSpace) {
560+
case SPIRAS_Global:
561+
return std::string(kOCLBuiltinName::ToGlobal);
562+
case SPIRAS_Local:
563+
return std::string(kOCLBuiltinName::ToLocal);
564+
case SPIRAS_Private:
565+
return std::string(kOCLBuiltinName::ToPrivate);
566+
default:
567+
llvm_unreachable("Invalid address space");
568+
return std::string();
569+
}
570+
},
571+
&Attrs);
572+
}
573+
544574
void SPIRVToOCLBase::visitCallSPIRVCvtBuiltin(CallInst *CI, Op OC,
545575
StringRef DemangledName) {
546576
AttributeList Attrs = CI->getCalledFunction()->getAttributes();

llvm-spirv/lib/SPIRV/SPIRVToOCL.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ class SPIRVToOCLBase : public InstVisitor<SPIRVToOCLBase> {
103103
/// intel_sub_group_media_block_write
104104
void visitCallSPIRVImageMediaBlockBuiltin(CallInst *CI, Op OC);
105105

106+
/// Transform __spirv_OpGenericCastToPtrExplicit_To{Global|Local|Private} to
107+
/// to_{global|local|private} OCL builtin.
108+
void visitCallGenericCastToPtrExplicitBuiltIn(CallInst *CI, Op OC);
109+
106110
/// Transform __spirv_*Convert_R{ReturnType}{_sat}{_rtp|_rtn|_rtz|_rte} to
107111
/// convert_{ReturnType}_{sat}{_rtp|_rtn|_rtz|_rte}
108112
/// example: <2 x i8> __spirv_SatConvertUToS(<2 x i32>) =>

llvm-spirv/test/transcoding/GenericCastToPtr.cl

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
// RUN: llvm-spirv %t.bc -o %t.spv
44
// RUN: spirv-val %t.spv
55
// RUN: llvm-spirv -r %t.spv -o %t.rev.bc
6-
// RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
6+
// RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefixes=CHECK-LLVM,CHECK-LLVM-OCL
7+
// RUN: llvm-spirv -r --spirv-target-env=SPV-IR %t.spv -o %t.rev.bc
8+
// RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefixes=CHECK-LLVM,CHECK-LLVM-SPV
9+
// RUN: llvm-spirv %t.rev.bc -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
710

811
// CHECK-SPIRV: 4 GenericCastToPtr
912

@@ -37,7 +40,8 @@ private short2 *testGenericCastToPtrPrivate(generic short2 *a) {
3740
// CHECK-LLVM-LABEL: @testGenericCastToPtrExplicitGlobal
3841
// CHECK-LLVM: %[[VoidPtrCast:[0-9]+]] = bitcast <2 x i16> addrspace(4)* %a to i8 addrspace(4)*
3942
// CHECK-LLVM-NEXT: %[[AddrSpaceCast:[0-9]+]] = bitcast i8 addrspace(4)* %[[VoidPtrCast]] to i8 addrspace(4)*
40-
// CHECK-LLVM-NEXT: %{{[0-9a-zA-Z.]+}} = call spir_func i8 addrspace(1)* @__to_global(i8 addrspace(4)* %[[AddrSpaceCast]])
43+
// CHECK-LLVM-OCL-NEXT: %{{[0-9a-zA-Z.]+}} = call spir_func i8 addrspace(1)* @__to_global(i8 addrspace(4)* %[[AddrSpaceCast]])
44+
// CHECK-LLVM-SPV-NEXT: %{{[0-9a-zA-Z.]+}} = call spir_func i8 addrspace(1)* @_Z41__spirv_GenericCastToPtrExplicit_ToGlobalPU3AS4ci(i8 addrspace(4)* %[[AddrSpaceCast]], i32
4145
// CHECK-LLVM: bitcast i8 addrspace(1)* %{{[0-9]+}} to <2 x i16> addrspace(1)*
4246

4347
global short2 *testGenericCastToPtrExplicitGlobal(generic short2 *a) {
@@ -49,7 +53,8 @@ global short2 *testGenericCastToPtrExplicitGlobal(generic short2 *a) {
4953
// CHECK-LLVM-LABEL: @testGenericCastToPtrExplicitLocal
5054
// CHECK-LLVM: %[[VoidPtrCast:[0-9]+]] = bitcast <2 x i16> addrspace(4)* %a to i8 addrspace(4)*
5155
// CHECK-LLVM-NEXT: %[[AddrSpaceCast:[0-9]+]] = bitcast i8 addrspace(4)* %[[VoidPtrCast]] to i8 addrspace(4)*
52-
// CHECK-LLVM-NEXT: %{{[0-9a-zA-Z.]+}} = call spir_func i8 addrspace(3)* @__to_local(i8 addrspace(4)* %[[AddrSpaceCast]])
56+
// CHECK-LLVM-OCL-NEXT: %{{[0-9a-zA-Z.]+}} = call spir_func i8 addrspace(3)* @__to_local(i8 addrspace(4)* %[[AddrSpaceCast]])
57+
// CHECK-LLVM-SPV-NEXT: %{{[0-9a-zA-Z.]+}} = call spir_func i8 addrspace(3)* @_Z40__spirv_GenericCastToPtrExplicit_ToLocalPU3AS4ci(i8 addrspace(4)* %[[AddrSpaceCast]], i32
5358
// CHECK-LLVM: bitcast i8 addrspace(3)* %{{[0-9]+}} to <2 x i16> addrspace(3)*
5459

5560
local short2 *testGenericCastToPtrExplicitLocal(generic short2 *a) {
@@ -61,7 +66,8 @@ local short2 *testGenericCastToPtrExplicitLocal(generic short2 *a) {
6166
// CHECK-LLVM-LABEL: @testGenericCastToPtrExplicitPrivate
6267
// CHECK-LLVM: %[[VoidPtrCast:[0-9]+]] = bitcast <2 x i16> addrspace(4)* %a to i8 addrspace(4)*
6368
// CHECK-LLVM-NEXT: %[[AddrSpaceCast:[0-9]+]] = bitcast i8 addrspace(4)* %[[VoidPtrCast]] to i8 addrspace(4)*
64-
// CHECK-LLVM-NEXT: %{{[0-9a-zA-Z.]+}} = call spir_func i8* @__to_private(i8 addrspace(4)* %[[AddrSpaceCast]])
69+
// CHECK-LLVM-OCL-NEXT: %{{[0-9a-zA-Z.]+}} = call spir_func i8* @__to_private(i8 addrspace(4)* %[[AddrSpaceCast]])
70+
// CHECK-LLVM-SPV-NEXT: %{{[0-9a-zA-Z.]+}} = call spir_func i8* @_Z42__spirv_GenericCastToPtrExplicit_ToPrivatePU3AS4ci(i8 addrspace(4)* %[[AddrSpaceCast]], i32
6571
// CHECK-LLVM: bitcast i8* %{{[0-9]+}} to <2 x i16>*
6672

6773
private short2 *testGenericCastToPtrExplicitPrivate(generic short2 *a) {

0 commit comments

Comments
 (0)