With the current behavior the following example yields a linker error:
"multiple definition of `foo.default'"
// Translation Unit 1
__attribute__((target_clones("dotprod, sve"))) int foo(void) { return 1; }
// Translation Unit 2
int foo(void) { return 0; }
__attribute__((target_version("dotprod"))) int foo(void);
__attribute__((target_version("sve"))) int foo(void);
int bar(void) { return foo(); }
That is because foo.default is generated twice. As a user I don't find
this particularly intuitive. If I wanted the default to be generated in
TU1 I'd rather write target_clones("dotprod, sve", "default")
explicitly.
When changing the code I noticed that the RISC-V target defers the
resolver emission when encountering a target_version definition. This
seems accidental since it only makes sense for AArch64, where we only
emit a resolver once we've processed the entire TU, and only if the
default version is present. I've changed this so that RISC-V immediately
emmits the resolver. I adjusted the codegen tests since the functions
now appear in a different order.
Implements https://github.com/ARM-software/acle/pull/377
25 lines
1.2 KiB
C
25 lines
1.2 KiB
C
// RUN: %clang_cc1 -triple aarch64-linux-gnu -verify -emit-llvm-only %s -DCHECK_IMPLICIT_DEFAULT
|
|
// RUN: %clang_cc1 -triple aarch64-linux-gnu -verify -emit-llvm-only %s -DCHECK_EXPLICIT_DEFAULT
|
|
|
|
#if defined(CHECK_IMPLICIT_DEFAULT)
|
|
|
|
int implicit_default_ok(void) { return 0; }
|
|
__attribute__((target_clones("aes", "lse"))) int implicit_default_ok(void) { return 1; }
|
|
|
|
int implicit_default_bad(void) { return 0; }
|
|
// expected-error@+2 {{definition with same mangled name 'implicit_default_bad.default' as another definition}}
|
|
// expected-note@-2 {{previous definition is here}}
|
|
__attribute__((target_clones("aes", "lse", "default"))) int implicit_default_bad(void) { return 1; }
|
|
|
|
#elif defined(CHECK_EXPLICIT_DEFAULT)
|
|
|
|
__attribute__((target_version("default"))) int explicit_default_ok(void) { return 0; }
|
|
__attribute__((target_clones("aes", "lse"))) int explicit_default_ok(void) { return 1; }
|
|
|
|
__attribute__((target_version("default"))) int explicit_default_bad(void) { return 0; }
|
|
// expected-error@+2 {{definition with same mangled name 'explicit_default_bad.default' as another definition}}
|
|
// expected-note@-2 {{previous definition is here}}
|
|
__attribute__((target_clones("aes", "lse", "default"))) int explicit_default_bad(void) { return 1; }
|
|
|
|
#endif
|