Skip to content

Commit c81f6ae

Browse files
EbinJose2002mahesh-attarde
authored andcommitted
[SPIRV] Add support for the extension SPV_EXT_relaxed_printf_string_address_space (llvm#160245)
Added support for the extension to support more storageclass for printf strings.
1 parent f2993ac commit c81f6ae

File tree

4 files changed

+107
-1
lines changed

4 files changed

+107
-1
lines changed

llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,10 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
148148
SPIRV::Extension::Extension::SPV_KHR_float_controls2},
149149
{"SPV_INTEL_tensor_float32_conversion",
150150
SPIRV::Extension::Extension::SPV_INTEL_tensor_float32_conversion},
151-
{"SPV_KHR_bfloat16", SPIRV::Extension::Extension::SPV_KHR_bfloat16}};
151+
{"SPV_KHR_bfloat16", SPIRV::Extension::Extension::SPV_KHR_bfloat16},
152+
{"SPV_EXT_relaxed_printf_string_address_space",
153+
SPIRV::Extension::Extension::
154+
SPV_EXT_relaxed_printf_string_address_space}};
152155

153156
bool SPIRVExtensionsParser::parse(cl::Option &O, StringRef ArgName,
154157
StringRef ArgValue,

llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,31 @@ static void AddDotProductRequirements(const MachineInstr &MI,
12221222
}
12231223
}
12241224

1225+
void addPrintfRequirements(const MachineInstr &MI,
1226+
SPIRV::RequirementHandler &Reqs,
1227+
const SPIRVSubtarget &ST) {
1228+
SPIRVGlobalRegistry *GR = ST.getSPIRVGlobalRegistry();
1229+
const SPIRVType *PtrType = GR->getSPIRVTypeForVReg(MI.getOperand(4).getReg());
1230+
if (PtrType) {
1231+
MachineOperand ASOp = PtrType->getOperand(1);
1232+
if (ASOp.isImm()) {
1233+
unsigned AddrSpace = ASOp.getImm();
1234+
if (AddrSpace != SPIRV::StorageClass::UniformConstant) {
1235+
if (!ST.canUseExtension(
1236+
SPIRV::Extension::
1237+
SPV_EXT_relaxed_printf_string_address_space)) {
1238+
report_fatal_error("SPV_EXT_relaxed_printf_string_address_space is "
1239+
"required because printf uses a format string not "
1240+
"in constant address space.",
1241+
false);
1242+
}
1243+
Reqs.addExtension(
1244+
SPIRV::Extension::SPV_EXT_relaxed_printf_string_address_space);
1245+
}
1246+
}
1247+
}
1248+
}
1249+
12251250
static bool isBFloat16Type(const SPIRVType *TypeDef) {
12261251
return TypeDef && TypeDef->getNumOperands() == 3 &&
12271252
TypeDef->getOpcode() == SPIRV::OpTypeFloat &&
@@ -1321,6 +1346,12 @@ void addInstrRequirements(const MachineInstr &MI,
13211346
static_cast<int64_t>(
13221347
SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
13231348
Reqs.addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
1349+
break;
1350+
}
1351+
if (MI.getOperand(3).getImm() ==
1352+
static_cast<int64_t>(SPIRV::OpenCLExtInst::printf)) {
1353+
addPrintfRequirements(MI, Reqs, ST);
1354+
break;
13241355
}
13251356
break;
13261357
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_EXT_relaxed_printf_string_address_space %s -o - | FileCheck %s
2+
; RUN: not llc -O0 -mtriple=spirv32-unknown-unknown %s -o %t.spvt 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
3+
4+
; CHECK: OpExtension "SPV_EXT_relaxed_printf_string_address_space"
5+
; CHECK: %[[#]] = OpExtInst %[[#]] %[[#]] printf
6+
7+
; CHECK-ERROR: LLVM ERROR: SPV_EXT_relaxed_printf_string_address_space is required because printf uses a format string not in constant address space.
8+
9+
@.str = private unnamed_addr addrspace(1) constant [4 x i8] c"%d\0A\00", align 1
10+
11+
declare spir_func i32 @printf(ptr addrspace(4), ...)
12+
13+
define spir_kernel void @test_kernel() {
14+
entry:
15+
; Format string in addrspace(1) → cast to addrspace(4)
16+
%format = addrspacecast ptr addrspace(1) @.str to ptr addrspace(4)
17+
%val = alloca i32, align 4
18+
store i32 123, ptr %val, align 4
19+
%loaded = load i32, ptr %val, align 4
20+
21+
; Call printf with non-constant format string
22+
%call = call spir_func i32 (ptr addrspace(4), ...) @printf(ptr addrspace(4) %format, i32 %loaded)
23+
ret void
24+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_EXT_relaxed_printf_string_address_space %s -o - | FileCheck %s
2+
; RUN: not llc -O0 -mtriple=spirv32-unknown-unknown %s -o %t.spvt 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
3+
4+
; CHECK: OpExtension "SPV_EXT_relaxed_printf_string_address_space"
5+
; CHECK: %[[#ExtInstSetId:]] = OpExtInstImport "OpenCL.std"
6+
; CHECK-DAG: %[[#TypeInt32Id:]] = OpTypeInt 32 0
7+
; CHECK-DAG: %[[#TypeInt8Id:]] = OpTypeInt 8 0
8+
; CHECK-DAG: %[[#TypeInt64Id:]] = OpTypeInt 64 0
9+
; CHECK-DAG: %[[#TypeArrayId:]] = OpTypeArray %[[#TypeInt8Id]] %[[#]]
10+
; CHECK-DAG: %[[#ConstantStorClassGlobalPtrTy:]] = OpTypePointer UniformConstant %[[#TypeArrayId]]
11+
; CHECK-DAG: %[[#WGStorClassGlobalPtrTy:]] = OpTypePointer Workgroup %[[#TypeArrayId]]
12+
; CHECK-DAG: %[[#CrossWFStorClassGlobalPtrTy:]] = OpTypePointer CrossWorkgroup %[[#TypeArrayId]]
13+
; CHECK-DAG: %[[#FunctionStorClassPtrTy:]] = OpTypePointer Function %[[#TypeInt8Id]]
14+
; CHECK-DAG: %[[#WGStorClassPtrTy:]] = OpTypePointer Workgroup %[[#TypeInt8Id]]
15+
; CHECK-DAG: %[[#CrossWFStorClassPtrTy:]] = OpTypePointer CrossWorkgroup %[[#TypeInt8Id]]
16+
; CHECK: %[[#ConstantCompositeId:]] = OpConstantComposite %[[#TypeArrayId]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]]
17+
; CHECK: %[[#]] = OpVariable %[[#ConstantStorClassGlobalPtrTy]] UniformConstant %[[#ConstantCompositeId]]
18+
; CHECK: %[[#]] = OpVariable %[[#CrossWFStorClassGlobalPtrTy]] CrossWorkgroup %[[#ConstantCompositeId]]
19+
; CHECK: %[[#]] = OpVariable %[[#WGStorClassGlobalPtrTy]] Workgroup %[[#ConstantCompositeId]]
20+
; CHECK: %[[#GEP1:]] = OpInBoundsPtrAccessChain %[[#FunctionStorClassPtrTy]] %[[#]] %[[#]] %[[#]]
21+
; CHECK: %[[#]] = OpExtInst %[[#TypeInt32Id]] %[[#ExtInstSetId:]] printf %[[#GEP1]]
22+
; CHECK: %[[#GEP2:]] = OpInBoundsPtrAccessChain %[[#CrossWFStorClassPtrTy]] %[[#]] %[[#]] %[[#]]
23+
; CHECK: %[[#]] = OpExtInst %[[#TypeInt32Id]] %[[#ExtInstSetId:]] printf %[[#GEP2]]
24+
; CHECK: %[[#GEP3:]] = OpInBoundsPtrAccessChain %[[#WGStorClassPtrTy]] %[[#]] %[[#]] %[[#]]
25+
; CHECK: %[[#]] = OpExtInst %[[#TypeInt32Id]] %[[#ExtInstSetId:]] printf %[[#GEP3]]
26+
27+
; CHECK-ERROR: LLVM ERROR: SPV_EXT_relaxed_printf_string_address_space is required because printf uses a format string not in constant address space.
28+
29+
@0 = internal unnamed_addr addrspace(2) constant [6 x i8] c"Test\0A\00", align 1
30+
@1 = internal unnamed_addr addrspace(1) constant [6 x i8] c"Test\0A\00", align 1
31+
@2 = internal unnamed_addr addrspace(3) constant [6 x i8] c"Test\0A\00", align 1
32+
33+
define spir_kernel void @test() {
34+
%tmp1 = alloca [6 x i8], align 1
35+
call void @llvm.memcpy.p0.p2.i64(ptr align 1 %tmp1, ptr addrspace(2) align 1 @0, i64 6, i1 false)
36+
%1 = getelementptr inbounds [6 x i8], ptr %tmp1, i32 0, i32 0
37+
%2 = call spir_func i32 @_Z18__spirv_ocl_printfPc(ptr %1)
38+
%3 = getelementptr inbounds [6 x i8], ptr addrspace(1) @1, i32 0, i32 0
39+
%4 = call spir_func i32 @_Z18__spirv_ocl_printfPU3AS1c(ptr addrspace(1) %3)
40+
%5 = getelementptr inbounds [6 x i8], ptr addrspace(3) @2, i32 0, i32 0
41+
%6 = call spir_func i32 @_Z18__spirv_ocl_printfPU3AS3c(ptr addrspace(3) %5)
42+
ret void
43+
}
44+
45+
declare spir_func i32 @_Z18__spirv_ocl_printfPc(ptr)
46+
declare spir_func i32 @_Z18__spirv_ocl_printfPU3AS1c(ptr addrspace(1))
47+
declare spir_func i32 @_Z18__spirv_ocl_printfPU3AS3c(ptr addrspace(3))
48+
declare void @llvm.memcpy.p0.p2.i64(ptr captures(none), ptr addrspace(2) captures(none) readonly, i64, i1)

0 commit comments

Comments
 (0)