Skip to content

Commit 7fd0952

Browse files
michalpaszkowskiigcbot
authored andcommitted
Fix kernel_arg_base_type for OpenCL type arguments
The metadata node !kernel_arg_base_type must mirror !kernel_arg_type for OpenCL builtin types (e.g. image1d_t). Unfortunately, this is inconsistent with LLVM 16-based Common Clang. This patch ensures that every OpenCL builtin type (*_t) listed in !kernel_arg_type is also present in !kernel_arg_base_type at the same position.
1 parent 3c5f226 commit 7fd0952

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

IGC/AdaptorOCL/preprocess_spvir/PreprocessSPVIR.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,61 @@ void PreprocessSPVIR::visitCallInst(CallInst& CI)
177177
}
178178
}
179179

180+
static void fixKernelArgBaseTypes(Module &M) {
181+
LLVMContext &Ctx = M.getContext();
182+
183+
for (Function &F : M) {
184+
if (F.isDeclaration())
185+
continue;
186+
187+
MDNode *TyMD = F.getMetadata("kernel_arg_type");
188+
MDNode *BaseMD = F.getMetadata("kernel_arg_base_type");
189+
if (!TyMD)
190+
continue;
191+
192+
if (!BaseMD) {
193+
// OpenCL base type node missing, copy all.
194+
F.setMetadata("kernel_arg_base_type", TyMD);
195+
continue;
196+
}
197+
198+
unsigned N = TyMD->getNumOperands();
199+
if (BaseMD->getNumOperands() != N) {
200+
// Mismatched sizes.
201+
continue;
202+
}
203+
204+
bool NeedPatch = false;
205+
SmallVector<Metadata *, 8> NewBase;
206+
NewBase.reserve(N);
207+
208+
for (unsigned i = 0; i < N; ++i) {
209+
auto *TyStr = dyn_cast<MDString>(TyMD->getOperand(i));
210+
auto *BaseStr = dyn_cast<MDString>(BaseMD->getOperand(i));
211+
// Keep original if found non‑MDString.
212+
if (!TyStr || !BaseStr) {
213+
NewBase.push_back(BaseMD->getOperand(i));
214+
continue;
215+
}
216+
217+
StringRef Ty = TyStr->getString();
218+
StringRef Base = BaseStr->getString();
219+
220+
if (Ty.endswith("_t") && Ty != Base) {
221+
NeedPatch = true;
222+
NewBase.push_back(MDString::get(Ctx, Ty));
223+
} else {
224+
NewBase.push_back(BaseStr);
225+
}
226+
}
227+
228+
if (NeedPatch) {
229+
MDNode *Patched = MDNode::get(Ctx, NewBase);
230+
F.setMetadata("kernel_arg_base_type", Patched);
231+
}
232+
}
233+
}
234+
180235
bool PreprocessSPVIR::runOnModule(Module& M) {
181236
m_Module = static_cast<IGCLLVM::Module*>(&M);
182237
IRBuilder<> builder(M.getContext());
@@ -188,6 +243,13 @@ bool PreprocessSPVIR::runOnModule(Module& M) {
188243

189244
visit(M);
190245

246+
// Ensure that every OpenCL builtin type (*_t) listed in !kernel_arg_type is
247+
// also present in !kernel_arg_base_type at the same position. Some
248+
// frontends with partial TargetExtTy support emit pointer types in
249+
// !kernel_arg_base_type (instead of an actual OpenCL builtin type), this is
250+
// incorrect and inconsistent with the prior behavior.
251+
fixKernelArgBaseTypes(M);
252+
191253
// Retype function arguments of OpenCL types represented as TargetExtTy to
192254
// use opaque pointers instead. This is necessary to match function
193255
// signatures generated by Clang, given that it only has partial TargetExtTy

IGC/Compiler/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ void initializeIGCFunctionExternalRegPressureAnalysisPass(llvm::PassRegistry&);
271271
void initializePromoteConstantStructsPass(llvm::PassRegistry&);
272272
void initializeLowerInvokeSIMDPass(llvm::PassRegistry&);
273273
void initializeRemoveCodeAssumptionsPass(llvm::PassRegistry&);
274+
void initializePreprocessSPVIRPass(llvm::PassRegistry&);
274275
void initializePromoteBoolsPass(llvm::PassRegistry&);
275276
void initializeResolveConstExprCallsPass(llvm::PassRegistry&);
276277
void initializeHandleSpirvDecorationMetadataPass(llvm::PassRegistry&);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2025 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
9+
; REQUIRES: llvm-16-plus
10+
; RUN: igc_opt --opaque-pointers -igc-preprocess-spvir -S < %s | FileCheck %s
11+
12+
; The second element of !kernel_arg_base_type is deliberately wrong
13+
; ("char*" instead of "image1d_t"). The pass must make the node
14+
; identical to !kernel_arg_type.
15+
16+
define spir_kernel void @testKernel(target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 2) %img, ptr addrspace(1) %newImg, target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 1) %storeResultsImg) !kernel_arg_type !0 !kernel_arg_base_type !1 {
17+
ret void
18+
}
19+
20+
!0 = !{!"image1d_t", !"image1d_t", !"image1d_t"}
21+
!1 = !{!"image1d_t", !"char*", !"image1d_t"}
22+
23+
; CHECK: !kernel_arg_base_type ![[BASE:[0-9]+]]
24+
; CHECK: ![[BASE]] = !{!"image1d_t", !"image1d_t", !"image1d_t"}

0 commit comments

Comments
 (0)