From 01b9402c483365acb15aec42d1277467711e9e11 Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Tue, 24 Sep 2019 13:39:40 +0000 Subject: [PATCH] [AArch64] Don't split 64-bit constant stores to volatile location The optimisation to optimise: typedef unsigned long long u64; void bar(u64 *x) { *x = 0xabcdef10abcdef10; } from: mov x1, 61200 movk x1, 0xabcd, lsl 16 movk x1, 0xef10, lsl 32 movk x1, 0xabcd, lsl 48 str x1, [x0] into: mov w1, 61200 movk w1, 0xabcd, lsl 16 stp w1, w1, [x0] ends up producing two distinct stores if the destination is volatile: void bar(u64 *x) { *(volatile u64 *)x = 0xabcdef10abcdef10; } mov w1, 61200 movk w1, 0xabcd, lsl 16 str w1, [x0] str w1, [x0, 4] because we end up not merging the strs into an stp. It's questionable whether the use of STP is valid for volatile in the first place. To avoid unnecessary pain in a context where it's unlikely to be performance critical [1] (use of volatile), this patch avoids this transformation for volatile destinations, so we produce the original single STR-X. Bootstrapped and tested on aarch64-none-linux-gnu. [1] https://lore.kernel.org/lkml/20190821103200.kpufwtviqhpbuv2n@willie-the-truck/ * config/aarch64/aarch64.md (mov): Don't call aarch64_split_dimode_const_store on volatile MEM. * gcc.target/aarch64/nosplit-di-const-volatile_1.c: New test. From-SVN: r276098 --- gcc/ChangeLog | 5 +++++ gcc/config/aarch64/aarch64.md | 4 ++-- gcc/testsuite/ChangeLog | 4 ++++ .../aarch64/nosplit-di-const-volatile_1.c | 15 +++++++++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/nosplit-di-const-volatile_1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0f8c0b0baa5..c163e61758a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-24 Kyrylo Tkachov + + * config/aarch64/aarch64.md (mov): Don't call + aarch64_split_dimode_const_store on volatile MEM. + 2019-09-24 Stamatis Markianos-Wright * config/aarch64/aarch64-option-extensions.def (fp16fml): diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index e4f9005c27f..edeaa6fe785 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -1104,8 +1104,8 @@ (match_operand:GPI 1 "general_operand"))] "" " - if (MEM_P (operands[0]) && CONST_INT_P (operands[1]) - && mode == DImode + if (MEM_P (operands[0]) && !MEM_VOLATILE_P (operands[0]) + && CONST_INT_P (operands[1]) && mode == DImode && aarch64_split_dimode_const_store (operands[0], operands[1])) DONE; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 582a2a4c69f..55b3bab945b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-24 Kyrylo Tkachov + + * gcc.target/aarch64/nosplit-di-const-volatile_1.c: New test. + 2019-09-24 Jakub Jelinek PR middle-end/91866 diff --git a/gcc/testsuite/gcc.target/aarch64/nosplit-di-const-volatile_1.c b/gcc/testsuite/gcc.target/aarch64/nosplit-di-const-volatile_1.c new file mode 100644 index 00000000000..da5975ad165 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/nosplit-di-const-volatile_1.c @@ -0,0 +1,15 @@ +/* Check that storing the 64-bit immediate to a volatile location is done + with a single store. */ + +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef unsigned long long u64; + +void bar (u64 *x) +{ + *(volatile u64 *)x = 0xabcdef10abcdef10ULL; +} + +/* { dg-final { scan-assembler-times "str\tx..?, .*" 1 } } */ +/* { dg-final { scan-assembler-not "str\tw..?, .*" } } */ -- 2.30.2