Skip to content

Commit 1ce1fc9

Browse files
MiloszSkobejkoigcbot
authored andcommitted
Skip llvm.global.annotations when applying referenced-indirectly attribute
When IGC is checking if function can be accessed indirecty it iterates over all function users looking for user that is not a function call. But when pointer to given function is in @llvm.global.annotations it will also be found and function will be marked as "referenced-indirectly", despite @llvm.global.annotations being used only for metadata and removed couple passes later in Dead Global Elimination Pass.
1 parent 0485266 commit 1ce1fc9

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

IGC/AdaptorCommon/ProcessFuncAttributes.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,30 @@ static void addAlwaysInlineForImageBuiltinUserFunctions(Module &M) {
411411
}
412412
}
413413

414+
static void collectGlobalAnnotationsPointers(const Module &M, DenseSet<const Value *> &GlobalAnnotations) {
415+
auto *GA = M.getGlobalVariable("llvm.global.annotations");
416+
if (!GA)
417+
return;
418+
419+
auto *CA = dyn_cast<ConstantArray>(GA->getInitializer());
420+
if (!CA)
421+
return;
422+
423+
for (Value *Op : CA->operands()) {
424+
auto *Annot = dyn_cast<ConstantStruct>(Op);
425+
if (!Annot)
426+
continue;
427+
428+
// In case of opaque pointers add whole struct, since it
429+
// will be visible as function user, otherwise add bitcast
430+
if (Annot->getOperand(0)->getType()->isOpaquePointerTy()) {
431+
GlobalAnnotations.insert(Annot);
432+
} else {
433+
GlobalAnnotations.insert(Annot->getOperand(0));
434+
}
435+
}
436+
}
437+
414438
bool ProcessFuncAttributes::runOnModule(Module &M) {
415439
MetaDataUtilsWrapper &mduw = getAnalysis<MetaDataUtilsWrapper>();
416440
MetaDataUtils *pMdUtils = mduw.getMetaDataUtils();
@@ -436,6 +460,9 @@ bool ProcessFuncAttributes::runOnModule(Module &M) {
436460
}
437461
}
438462

463+
DenseSet<const Value *> GlobalAnnotationsPtr;
464+
collectGlobalAnnotationsPointers(M, GlobalAnnotationsPtr);
465+
439466
auto SetNoInline = [](Function *F) {
440467
F->addFnAttr(llvm::Attribute::NoInline);
441468
F->removeFnAttr(llvm::Attribute::AlwaysInline);
@@ -599,6 +626,11 @@ bool ProcessFuncAttributes::runOnModule(Module &M) {
599626
// Set the indirect flag if the function's address is taken by a non-call instruction.
600627
for (auto u = F->user_begin(), e = F->user_end(); u != e; u++) {
601628
CallInst *call = dyn_cast<CallInst>(*u);
629+
630+
// If user is function bitcast or function ptr in @llvm.global.annotations we should skip it.
631+
if (GlobalAnnotationsPtr.find(*u) != GlobalAnnotationsPtr.end())
632+
continue;
633+
602634
if (!call || IGCLLVM::getCalledValue(call) != F) {
603635
isIndirect = true;
604636
break;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2025 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
;
9+
; RUN: igc_opt --igc-process-func-attributes -S < %s 2>&1 | FileCheck %s
10+
; ------------------------------------------------
11+
12+
; When pointer to function is in @llvm.global.annotations we should not
13+
; consider this user when applying "referenced-indirectly" attribute.
14+
15+
@0 = private unnamed_addr constant [9 x i8] zeroinitializer, section "llvm.metadata"
16+
@llvm.global.annotations = appending global [1 x { i8*, i8*, i8*, i32 }] [{ i8*, i8*, i8*, i32 } { i8* bitcast (void ()* @func to i8*), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @0, i32 0, i32 0), i8* undef, i32 undef }], section "llvm.metadata"
17+
18+
define internal spir_func void @func() #0 {
19+
ret void
20+
}
21+
22+
define spir_kernel void @kernel() {
23+
call void @func()
24+
ret void
25+
}
26+
27+
; CHECK-NOT: "referenced-indirectly"
28+
attributes #0 = { nounwind }
29+
30+
!igc.functions = !{!1}
31+
!1 = !{void ()* @kernel, !2}
32+
!2 = !{!3}
33+
!3 = !{!"function_type", i32 0}

0 commit comments

Comments
 (0)