]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[AArch64] Don't split 64-bit constant stores to volatile location
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Tue, 24 Sep 2019 13:39:40 +0000 (13:39 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Tue, 24 Sep 2019 13:39:40 +0000 (13:39 +0000)
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<mode>): 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
gcc/config/aarch64/aarch64.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/nosplit-di-const-volatile_1.c [new file with mode: 0644]

index 0f8c0b0baa5ec6cd0990fcae8905094c5e273f54..c163e61758a11fe2b9d292e51188840a216bbc24 100644 (file)
@@ -1,3 +1,8 @@
+2019-09-24  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/aarch64/aarch64.md (mov<mode>): Don't call
+       aarch64_split_dimode_const_store on volatile MEM.
+
 2019-09-24  Stamatis Markianos-Wright  <stam.markianos-wright@arm.com>
 
        * config/aarch64/aarch64-option-extensions.def (fp16fml):
index e4f9005c27f6f57efba31004389dbed9fd91a360..edeaa6fe785fc13fef10319e783634799f48ec7e 100644 (file)
        (match_operand:GPI 1 "general_operand"))]
   ""
   "
-    if (MEM_P (operands[0]) && CONST_INT_P (operands[1])
-       && <MODE>mode == DImode
+    if (MEM_P (operands[0]) && !MEM_VOLATILE_P (operands[0])
+       && CONST_INT_P (operands[1]) && <MODE>mode == DImode
        && aarch64_split_dimode_const_store (operands[0], operands[1]))
       DONE;
 
index 582a2a4c69f03948252a1b136cf9632b3fe6e74b..55b3bab945b9e8094010a2a0246e38732a55d688 100644 (file)
@@ -1,3 +1,7 @@
+2019-09-24  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * gcc.target/aarch64/nosplit-di-const-volatile_1.c: New test.
+
 2019-09-24  Jakub Jelinek  <jakub@redhat.com>
 
        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 (file)
index 0000000..da5975a
--- /dev/null
@@ -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..?, .*" } } */