For COMDAT functions, to remove the duplicate counters, we create a "__profv_*" COMDAT group for the profile data objects, so that only one set of profile data objects will be emitted in the final object.
This works fine until the we have the value profiling. In indirect-call value profile we record the function address to be used in the runtime. This is problematic for COMDAT functions with internal linkage (we do create such function, like global initializer). If we record the address of such function, We will create a reference to internal symbols in COMDAT. This violates the standard.
One can use the following two .ll files to reproduce the issue:
- a.ll ----
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
$_Z3foov = comdat any
@fp1 = global i32 ()* @_Z3foov, align 8
define internal i32 @_Z3foov() comdat {
entry:
ret i32 1
}
- end of b.ll ----
- b.ll ----
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
$_Z3foov = comdat any
@fp2 = global i32 ()* @_Z3foov, align 8
define internal i32 @_Z3foov() comdat {
entry:
ret i32 1
}
- end of b.ll ----
clang a.ll -c && clang b.ll -c && clang a.o b.o
We have the following warning:
"warning: relocation refers to discarded section"
This patch prohibits the recording the function address if it's internal and COMDAT.