The constraint "S" can only be used with a symbol that binds locally, so the following does not work for -fpie/-fpic (GOT access is used). ``` namespace ns { extern int var, a[4]; } void foo() { asm(".pushsection .xxx,\"aw\"; .dc.a %0; .popsection" :: "S"(&ns::var)); asm(".reloc ., BFD_RELOC_NONE, %0" :: "S"(&ns::a[3])); } ```
This is overly restrictive, as many references like an absolute relocation in a writable section or a non-SHF_ALLOC section should be totally fine. Allow symbols that do not bind locally, similar to aarch64 "S" and x86-64 "Ws" (commit d7250100381b817114447d91fff4748526d4fb21). gcc/ChangeLog: * config/riscv/constraints.md: Relax the condition for "S". * doc/md.texi: Update. gcc/testsuite/ChangeLog: * gcc.target/riscv/asm-raw-symbol.c: New test. --- gcc/config/riscv/constraints.md | 4 ++-- gcc/doc/md.texi | 2 +- gcc/testsuite/gcc.target/riscv/asm-raw-symbol.c | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/asm-raw-symbol.c diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index 41acaea04eb..bb012668fcb 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -121,8 +121,8 @@ (define_memory_constraint "A" (match_test "GET_CODE(XEXP(op,0)) == REG"))) (define_constraint "S" - "A constraint that matches an absolute symbolic address." - (match_operand 0 "absolute_symbolic_operand")) + "A symbolic reference or label reference." + (match_code "const,symbol_ref,label_ref")) (define_constraint "U" "@internal diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index b0c61925120..c75e5bf259d 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -1947,7 +1947,7 @@ Integer constant that is valid as an immediate operand in a 64-bit @code{MOV} pseudo instruction @item S -An absolute symbolic address or a label reference +A symbolic reference or label reference. @item Y Floating point constant zero diff --git a/gcc/testsuite/gcc.target/riscv/asm-raw-symbol.c b/gcc/testsuite/gcc.target/riscv/asm-raw-symbol.c new file mode 100644 index 00000000000..eadf6d23fe1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/asm-raw-symbol.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-fpic" } */ + +extern int var; + +void +func (void) +{ +label: + __asm__ ("@ %0" : : "S" (func)); + __asm__ ("@ %0" : : "S" (&var + 1)); + __asm__ ("@ %0" : : "S" (&&label)); +} + +/* { dg-final { scan-assembler "@ func" } } */ +/* { dg-final { scan-assembler "@ var\\+4" } } */ +/* { dg-final { scan-assembler "@ .L" } } */ -- 2.43.0.429.g432eaa2c6b-goog