While working on another MSR-related patch, I noticed that aarch64_write_sysregdi's constraints allowed zero, but its predicate didn't. This could in principle lead to an ICE during or after RA, since "Z" allows the RA to rematerialise a known zero directly into the instruction.
The usual techniques for exposing a bug like that didn't work in this case, since the optimisers seem to make no attempt to remove redundant zero moves (at least not for these unspec_volatiles). But the problem still seems worth fixing pre-emptively. Tested on aarch64-linux-gnu & pushed. Richard gcc/ * config/aarch64/aarch64.md (aarch64_read_sysregti): Change the source predicate to aarch64_reg_or_zero. gcc/testsuite/ * gcc.target/aarch64/acle/rwsr-4.c: New test. * gcc.target/aarch64/acle/rwsr-armv8p9.c: Avoid read of uninitialized variable. --- gcc/config/aarch64/aarch64.md | 2 +- gcc/testsuite/gcc.target/aarch64/acle/rwsr-4.c | 15 +++++++++++++++ .../gcc.target/aarch64/acle/rwsr-armv8p9.c | 4 +--- 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/rwsr-4.c diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index f8d82cee903..39655ea5e39 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -659,7 +659,7 @@ (define_insn "aarch64_read_sysregti" (define_insn "aarch64_write_sysregdi" [(unspec_volatile:DI [(match_operand 0 "aarch64_sysreg_string" "") - (match_operand:DI 1 "register_operand" "rZ")] + (match_operand:DI 1 "aarch64_reg_or_zero" "rZ")] UNSPEC_SYSREG_WDI)] "" "msr\t%0, %x1" diff --git a/gcc/testsuite/gcc.target/aarch64/acle/rwsr-4.c b/gcc/testsuite/gcc.target/aarch64/acle/rwsr-4.c new file mode 100644 index 00000000000..52fb603f3cf --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/rwsr-4.c @@ -0,0 +1,15 @@ +/* { dg-options "-O" } */ + +#include <stdint.h> +#include <arm_acle.h> + +void f(); +void g() +{ + int64_t x = 0; + __arm_wsr64("tpidr_el0", x); + f(); + __arm_wsr64("tpidr_el0", x); +} + +/* { dg-final { scan-assembler-times {\tmsr\t[^,]+, xzr\n} 2 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/acle/rwsr-armv8p9.c b/gcc/testsuite/gcc.target/aarch64/acle/rwsr-armv8p9.c index e2f297bbeeb..c49fbb5368e 100644 --- a/gcc/testsuite/gcc.target/aarch64/acle/rwsr-armv8p9.c +++ b/gcc/testsuite/gcc.target/aarch64/acle/rwsr-armv8p9.c @@ -3,10 +3,8 @@ /* { dg-options "-O2 -march=armv8.9-a" } */ #include <arm_acle.h> void -readwrite_armv8p9a_sysregs () +readwrite_armv8p9a_sysregs (long long int a) { - long long int a; - /* Write-only system registers. */ __arm_wsr64 ("pmzr_el0", a); /* { dg-final { scan-assembler "msr\ts3_3_c9_c13_4, x0" } } */ -- 2.25.1