Skip to content

Commit 6316cf3

Browse files
petechouArtem Gindinson
authored and
Artem Gindinson
committed
Relax the address space requirement of printf strings.
Follow SPV_EXT_relaxed_printf_string_address_space to relax the address space requirement of printf strings and accept non-constant address space printf strings. However, we expect it is the only exception and FE should produce a valid IGC input that satisfies any other OpenCL printf restrictions.
1 parent fd39a21 commit 6316cf3

File tree

3 files changed

+109
-36
lines changed

3 files changed

+109
-36
lines changed

IGC/Compiler/CISACodeGen/CISABuilder.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -5591,7 +5591,11 @@ namespace IGC
55915591
else
55925592
{
55935593
uint32_t type = vISA::GenSymType::S_GLOBAL_VAR_CONST;
5594-
if (addrSpace == ADDRESS_SPACE_GLOBAL)
5594+
// For Zebin always use constant type for string constants
5595+
// because of the relaxed address space requirement of
5596+
// printf strings.
5597+
IGC_ASSERT(modMD->stringConstants.empty() || m_program->GetContext()->enableZEBinary());
5598+
if (addrSpace == ADDRESS_SPACE_GLOBAL && !modMD->stringConstants.count(pGlobal))
55955599
type = vISA::GenSymType::S_GLOBAL_VAR;
55965600
if (!pGlobal->hasInitializer())
55975601
type = vISA::GenSymType::S_UNDEF;

IGC/Compiler/Optimizer/OpenCLPasses/ProgramScopeConstants/ProgramScopeConstantAnalysis.cpp

+44-35
Original file line numberDiff line numberDiff line change
@@ -129,49 +129,58 @@ bool ProgramScopeConstantAnalysis::runOnModule(Module& M)
129129
}
130130

131131
DataVector* inlineProgramScopeBuffer = nullptr;
132-
if (AS == ADDRESS_SPACE_GLOBAL)
132+
auto initInlineGlobalBuffer = [&]() {
133+
InlineProgramScopeBuffer ilpsb;
134+
ilpsb.alignment = 0;
135+
ilpsb.allocSize = 0;
136+
m_pModuleMd->inlineGlobalBuffers.push_back(ilpsb);
137+
hasInlineGlobalBuffer = true;
138+
};
139+
auto initInlineConstantBuffer = [&]() {
140+
// General constants
141+
InlineProgramScopeBuffer ilpsb;
142+
ilpsb.alignment = 0;
143+
ilpsb.allocSize = 0;
144+
m_pModuleMd->inlineConstantBuffers.push_back(ilpsb);
145+
146+
// String literals
147+
InlineProgramScopeBuffer ilpsbString;
148+
ilpsbString.alignment = 0;
149+
ilpsbString.allocSize = 0;
150+
m_pModuleMd->inlineConstantBuffers.push_back(ilpsbString);
151+
hasInlineConstantBuffer = true;
152+
};
153+
154+
// When ZeBin is enabled, constant variables that are string literals
155+
// used only by printf will be stored in the second constant buffer.
156+
ConstantDataSequential* cds = dyn_cast<ConstantDataSequential>(initializer);
157+
bool isZebinPrintfStringConst = Ctx->enableZEBinary() &&
158+
cds && (cds->isCString() || cds->isString()) &&
159+
OpenCLPrintfAnalysis::isPrintfOnlyStringConstant(globalVar);
160+
// Here we follow SPV_EXT_relaxed_printf_string_address_space to relax
161+
// the address space requirement of printf strings and accept
162+
// non-constant address space printf strings. However, we expect it is
163+
// the only exception and FE should produce a IGC input that satisfies
164+
// any other OpenCL printf restrictions.
165+
if (isZebinPrintfStringConst)
133166
{
134-
if (!hasInlineGlobalBuffer)
135-
{
136-
InlineProgramScopeBuffer ilpsb;
137-
ilpsb.alignment = 0;
138-
ilpsb.allocSize = 0;
139-
m_pModuleMd->inlineGlobalBuffers.push_back(ilpsb);
140-
hasInlineGlobalBuffer = true;
141-
}
142-
inlineProgramScopeBuffer = &m_pModuleMd->inlineGlobalBuffers.back().Buffer;
143-
167+
if (!hasInlineConstantBuffer)
168+
initInlineConstantBuffer();
169+
m_pModuleMd->stringConstants.insert(globalVar);
170+
inlineProgramScopeBuffer = &m_pModuleMd->inlineConstantBuffers[1].Buffer;
144171
}
145172
else
146173
{
147-
if (!hasInlineConstantBuffer)
148-
{
149-
// General constants
150-
InlineProgramScopeBuffer ilpsb;
151-
ilpsb.alignment = 0;
152-
ilpsb.allocSize = 0;
153-
m_pModuleMd->inlineConstantBuffers.push_back(ilpsb);
154-
155-
// String literals
156-
InlineProgramScopeBuffer ilpsbString;
157-
ilpsbString.alignment = 0;
158-
ilpsbString.allocSize = 0;
159-
m_pModuleMd->inlineConstantBuffers.push_back(ilpsbString);
160-
hasInlineConstantBuffer = true;
161-
}
162-
163-
// When ZeBin is enabled, constant variables that are string literals
164-
// used only by printf will be stored in the second const buffer.
165-
ConstantDataSequential* cds = dyn_cast<ConstantDataSequential>(initializer);
166-
bool isPrintfStringConst = cds && (cds->isCString() || cds->isString()) &&
167-
OpenCLPrintfAnalysis::isPrintfOnlyStringConstant(globalVar);
168-
if (Ctx->enableZEBinary() && isPrintfStringConst)
174+
if (AS == ADDRESS_SPACE_GLOBAL)
169175
{
170-
m_pModuleMd->stringConstants.insert(globalVar);
171-
inlineProgramScopeBuffer = &m_pModuleMd->inlineConstantBuffers[1].Buffer;
176+
if (!hasInlineGlobalBuffer)
177+
initInlineGlobalBuffer();
178+
inlineProgramScopeBuffer = &m_pModuleMd->inlineGlobalBuffers.back().Buffer;
172179
}
173180
else
174181
{
182+
if (!hasInlineConstantBuffer)
183+
initInlineConstantBuffer();
175184
inlineProgramScopeBuffer = &m_pModuleMd->inlineConstantBuffers[0].Buffer;
176185
}
177186
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2023 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
; REQUIRES: regkeys
9+
; RUN: igc_opt --serialize-igc-metadata -igc-programscope-constant-analysis \
10+
; RUN: -S -regkey EnableZEBinary=1 < %s | FileCheck %s
11+
; ------------------------------------------------
12+
; ProgramScopeConstantAnalysis
13+
; ------------------------------------------------
14+
15+
; Test checks that metadata can be updated correctly with non-constant address
16+
; space string constants after the address space requirement is relaxed when
17+
; EnableZEBinary=1
18+
19+
; CHECK: !{!"stringConstants",
20+
; CHECK-DAG: !{!"stringConstantsSet{{[[][0-9][]]}}", [3 x i8] addrspace(2)* @fmt_str}
21+
; CHECK-DAG: !{!"stringConstantsSet{{[[][0-9][]]}}", [3 x i8] addrspace(1)* @opencl_printf_str}
22+
; CHECK-DAG: !{!"stringConstantsSet{{[[][0-9][]]}}", [3 x i8] addrspace(1)* @sycl_v1_printf_str}
23+
; CHECK-DAG: !{!"stringConstantsSet{{[[][0-9][]]}}", [3 x i8] addrspace(1)* @sycl_v2_printf_str}
24+
; CHECK-DAG: !{!"stringConstantsSet{{[[][0-9][]]}}", [3 x i8] addrspace(1)* @cl_sycl_printf_str}
25+
26+
@fmt_str = internal unnamed_addr addrspace(2) constant [3 x i8] c"%s\00", align 1
27+
@opencl_printf_str = internal unnamed_addr addrspace(1) constant [3 x i8] c"A\0A\00", align 1
28+
@sycl_v1_printf_str = internal unnamed_addr addrspace(1) constant [3 x i8] c"B\0A\00", align 1
29+
@sycl_v2_printf_str = internal unnamed_addr addrspace(1) constant [3 x i8] c"C\0A\00", align 1
30+
@cl_sycl_printf_str = internal unnamed_addr addrspace(1) constant [3 x i8] c"D\0A\00", align 1
31+
32+
; decl of opencl printf
33+
declare spir_func i32 @printf(i8 addrspace(2)*, ...)
34+
35+
; decl of sycl v1 oneapi printf
36+
declare spir_func i32 @_ZN4sycl3_V13ext6oneapi12experimental6printfIU3AS2cJEEEiPKT_DpT0_(i8 addrspace(2)*, ...)
37+
38+
; decl of future sycl v2 oneapi printf
39+
declare spir_func i32 @_ZN4sycl3_V23ext6oneapi12experimental6printfIU3AS2cJEEEiPKT_DpT0_(i8 addrspace(2)*, ...)
40+
41+
; decl of deprecated cl sycl oneapi printf
42+
declare spir_func i32 @_ZN2cl4sycl3ext6oneapi12experimental6printfIU3AS2cJEEEiPKT_DpT0_(i8 addrspace(2)*, ...)
43+
44+
; Function Attrs: convergent noinline nounwind optnone
45+
define spir_func void @foo() {
46+
%1 = getelementptr inbounds [3 x i8], [3 x i8] addrspace(2)* @fmt_str, i32 0, i32 0
47+
%2 = getelementptr inbounds [3 x i8], [3 x i8] addrspace(1)* @opencl_printf_str, i64 0, i64 0
48+
%3 = addrspacecast i8 addrspace(1)* %2 to i8 addrspace(4)*
49+
%4 = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* %1, i8 addrspace(4)* %3)
50+
%5 = getelementptr inbounds [3 x i8], [3 x i8] addrspace(1)* @sycl_v1_printf_str, i64 0, i64 0
51+
%6 = addrspacecast i8 addrspace(1)* %5 to i8 addrspace(4)*
52+
%7 = call spir_func i32 (i8 addrspace(2)*, ...) @_ZN4sycl3_V13ext6oneapi12experimental6printfIU3AS2cJEEEiPKT_DpT0_(i8 addrspace(2)* %1, i8 addrspace(4)* %6)
53+
%8 = getelementptr inbounds [3 x i8], [3 x i8] addrspace(1)* @sycl_v2_printf_str, i64 0, i64 0
54+
%9 = addrspacecast i8 addrspace(1)* %8 to i8 addrspace(4)*
55+
%10 = call spir_func i32 (i8 addrspace(2)*, ...) @_ZN4sycl3_V23ext6oneapi12experimental6printfIU3AS2cJEEEiPKT_DpT0_(i8 addrspace(2)* %1, i8 addrspace(4)* %9)
56+
%11 = getelementptr inbounds [3 x i8], [3 x i8] addrspace(1)* @cl_sycl_printf_str, i64 0, i64 0
57+
%12 = addrspacecast i8 addrspace(1)* %11 to i8 addrspace(4)*
58+
%13 = call spir_func i32 (i8 addrspace(2)*, ...) @_ZN2cl4sycl3ext6oneapi12experimental6printfIU3AS2cJEEEiPKT_DpT0_(i8 addrspace(2)* %1, i8 addrspace(4)* %12)
59+
ret void
60+
}

0 commit comments

Comments
 (0)