I initially assumed only kernels could be roots, but that is wrong. A function with no callers also needs to be a root to ensure it is correctly handled. They're very rare because we usually internalize everything, and internal functions with no callers would be deleted. When they are present, we need to also consider their dependencies and act accordingly. Previously, we could put a function "by default" in P0, but it could call another function with internal linkage defined in another module which was of course incorrect. Fixes SWDEV-467695
37 lines
767 B
LLVM
37 lines
767 B
LLVM
; RUN: llvm-split -o %t %s -j 2 -mtriple amdgcn-amd-amdhsa -debug 2>&1 | FileCheck %s --implicit-check-not="[root]"
|
|
; REQUIRES: asserts
|
|
|
|
; func_3 is never directly called, it needs to be considered
|
|
; as a root to handle this module correctly.
|
|
|
|
; CHECK: [root] kernel_1
|
|
; CHECK-NEXT: [dependency] func_1
|
|
; CHECK-NEXT: [dependency] func_2
|
|
; CHECK-NEXT: [root] func_3
|
|
; CHECK-NEXT: [dependency] func_2
|
|
|
|
define amdgpu_kernel void @kernel_1() {
|
|
entry:
|
|
call void @func_1()
|
|
ret void
|
|
}
|
|
|
|
define linkonce_odr hidden void @func_1() {
|
|
entry:
|
|
%call = call i32 @func_2()
|
|
ret void
|
|
}
|
|
|
|
define linkonce_odr hidden i32 @func_2() #0 {
|
|
entry:
|
|
ret i32 0
|
|
}
|
|
|
|
define void @func_3() {
|
|
entry:
|
|
%call = call i32 @func_2()
|
|
ret void
|
|
}
|
|
|
|
attributes #0 = { noinline optnone }
|