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.
I do not know yet much about COMDAT's. I need to read about them. Otherwise, the check is fine. But, I'd prefer it to be placed after line 244. There we reduce the linkages to check for to one of linkonce, local or available externally. I'd also like to check if the same warning shows up for either of linkonce or available externally linkages.