For the testcase in PR127633 we combine two adjacent DFmode loads from
the stack into a V2DFmode via a peephole2 that uses adjust_address.
That unfortunately leaves both the MEM_EXPR and the MEM_ALIAS_SET
unaltered causing later scheduling to move the widened load before
the store.  The fix is to instead use widen_memory_access which
attempts to fixup MEM_EXPR and resets MEM_ALIAS_SET.

To avoid regressing gcc.target/i386/sse{2,4_1}-init-v2df-2.c where
ix86_split_stlf_stall_load splitted a V2DF load from a parameter
but this being no longer visible with a cleared MEM_EXPR this
adjusts ix86_operands_ok_for_move_multiple instead to avoid
merging two loads from different parameters, not only those
that ix86_split_stlf_stall_load handles.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

OK?

Thanks,
Richard.

        PR target/127633
        * config/i386/sse.md (movsd/movhpd to movupd): Use
        widen_memory_access instead of adjust_address to merge
        the MEMs.
        * config/i386/i386.cc (ix86_operands_ok_for_move_multiple):
        Avoid merging loads from different parameters.

        * gcc.dg/pr127633.c: New testcase.
        * gcc.target/i386/sse2-init-v2df-2.c: Adjust.
        * gcc.target/i386/sse4_1-init-v2df-2.c: Likewise.
---
 gcc/config/i386/i386.cc                       |  9 +++
 gcc/config/i386/sse.md                        |  6 +-
 gcc/testsuite/gcc.dg/pr127633.c               | 68 +++++++++++++++++++
 .../gcc.target/i386/sse2-init-v2df-2.c        |  4 +-
 .../gcc.target/i386/sse4_1-init-v2df-2.c      |  4 +-
 5 files changed, 84 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr127633.c

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index b09a5077820..74a6b39856f 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -28079,6 +28079,15 @@ ix86_operands_ok_for_move_multiple (rtx *operands, 
bool load,
     {
       mem_1 = operands[1];
       mem_2 = operands[3];
+      /* Avoid fusing two loads from distinct parameters as that might
+        cause STLF failure.  */
+      tree base_1;
+      if (MEM_EXPR (mem_1)
+         && MEM_EXPR (mem_2)
+         && (TREE_CODE (base_1 = get_base_address (MEM_EXPR (mem_1)))
+             == PARM_DECL)
+         && get_base_address (MEM_EXPR (mem_2)) != base_1)
+       return false;
       reg_1 = operands[0];
       reg_2 = operands[2];
     }
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 0ce82789dc6..2b6d7de1f7f 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -2021,7 +2021,7 @@
   "TARGET_SSE2 && TARGET_SSE_UNALIGNED_LOAD_OPTIMAL
    && ix86_operands_ok_for_move_multiple (operands, true, DFmode)"
   [(set (match_dup 2) (match_dup 5))]
-  "operands[5] = adjust_address (operands[1], V2DFmode, 0);")
+  "operands[5] = widen_memory_access (operands[1], V2DFmode, 0);")
 
 (define_peephole2
   [(set (match_operand:DF 0 "sse_reg_operand")
@@ -2033,7 +2033,7 @@
    && REGNO (operands[4]) == REGNO (operands[2])
    && ix86_operands_ok_for_move_multiple (operands, true, DFmode)"
   [(set (match_dup 2) (match_dup 5))]
-  "operands[5] = adjust_address (operands[1], V2DFmode, 0);")
+  "operands[5] = widen_memory_access (operands[1], V2DFmode, 0);")
 
 ;; Merge movlpd/movhpd to movupd for TARGET_SSE_UNALIGNED_STORE_OPTIMAL 
targets.
 (define_peephole2
@@ -2046,7 +2046,7 @@
   "TARGET_SSE2 && TARGET_SSE_UNALIGNED_STORE_OPTIMAL
    && ix86_operands_ok_for_move_multiple (operands, false, DFmode)"
   [(set (match_dup 4) (match_dup 1))]
-  "operands[4] = adjust_address (operands[0], V2DFmode, 0);")
+  "operands[4] = widen_memory_access (operands[0], V2DFmode, 0);")
 
 (define_insn "<sse3>_lddqu<avxsizesuffix>"
   [(set (match_operand:VI1 0 "register_operand" "=x,x")
diff --git a/gcc/testsuite/gcc.dg/pr127633.c b/gcc/testsuite/gcc.dg/pr127633.c
new file mode 100644
index 00000000000..500e84f66ff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr127633.c
@@ -0,0 +1,68 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+/* { dg-options "-O3 -funroll-all-loops -fno-vect-cost-model" } */
+
+int d, ab = -104, ac, ad = -170, ae = -51, af = -151, ag = -1966532803, ah, ai,
+       aj, ak, al, am, an, *ao, v, ap, aq;
+short w, y, z, ar, as, at, au, av, aw, ax = -156, ay, az, ba;
+long bb = -38, bc, bd, be, bf;
+double bg, bh, *bi;
+char bj;
+int a(unsigned bk, unsigned bl) {
+  return bk^bl;
+}
+[[gnu::noinline,gnu::noclone]]
+int aa(short bn) {
+  return bn;
+}
+[[gnu::noinline,gnu::noclone]]
+int s(long bk, short bl, short bm, long bn, int bo, short bp, int bq) {
+  int bt, bu = aa(-1);
+  double bv, bw, *by, *bz, **ca;
+  __attribute__((__vector_size__(8 * sizeof(double)))) double cb;
+  cb[4] = 1.75;
+  cb[5] = -8.0;
+  cb[7] = 1.75;
+  ca = &by;
+  bt = bu;
+  bv = -65536;
+  bz = &bw;
+  cb[2] = 0 + (bm ? -8.0 : bg);
+  if (-bl >= 0) {
+    if (bm)
+      goto bx;
+    ca = &bz;
+  }
+  cb[3] = 524420 + bt;
+  az = bl - (1646 ^ bl);
+  bw = 2.0 * bv;
+  bv = 2.0 * bw;
+  *ca = &bv;
+bx:
+  cb[1] = -4.0 + 2.5 * bv;
+  bc = 267503909 - bn;
+  bi = *ca;
+  *by = 131072 - 5.0 * bw;
+  *bz = 3.0 * bg + 0.375 * bv;
+  ay = ba = bl + 15 * az;
+  bj = -__builtin_popcount((unsigned char)(109 + az));
+  an = 0;
+  
+  an = a(an, cb[1]);
+  an = a(an, cb[2]);
+  an = a(an, cb[3]);
+  an = a(an, cb[4]);
+  an = a(an, cb[5]);
+  an = a(an, cb[7]);
+
+  an = a(an, bw);
+  an = an^(int)bg;
+  return an;
+}
+int main() {
+  am = s(1, 1, 1, 1, 3, 1, 1);
+  al = am;
+  if (al != 0xfff97f7f)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v2df-2.c 
b/gcc/testsuite/gcc.target/i386/sse2-init-v2df-2.c
index 3f58098af8d..17131422939 100644
--- a/gcc/testsuite/gcc.target/i386/sse2-init-v2df-2.c
+++ b/gcc/testsuite/gcc.target/i386/sse2-init-v2df-2.c
@@ -15,9 +15,9 @@ v2df f0m() { return (v2df){ 0.0, m }; }
 v2df fmm() { return (v2df){ m, m }; }
 v2df fmn() { return (v2df){ m, n }; }
 
-/* { dg-final { scan-assembler-times "movq" 5 } } */
+/* { dg-final { scan-assembler-times "movq" 4 } } */
 /* { dg-final { scan-assembler-times "pslldq" 2 } } */
 /* { dg-final { scan-assembler-times "unpcklpd" 2 } } */
-/* { dg-final { scan-assembler-times "movsd" 3 } } */
+/* { dg-final { scan-assembler-times "movsd" 4 } } */
 /* { dg-final { scan-assembler-times "movhpd" 2 } } */
 
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-2.c 
b/gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-2.c
index 218cc8bf896..f1d8e8367aa 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-2.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-init-v2df-2.c
@@ -15,9 +15,9 @@ v2df f0m() { return (v2df){ 0.0, m }; }
 v2df fmm() { return (v2df){ m, m }; }
 v2df fmn() { return (v2df){ m, n }; }
 
-/* { dg-final { scan-assembler-times "movq" 5 } } */
+/* { dg-final { scan-assembler-times "movq" 4 } } */
 /* { dg-final { scan-assembler-times "pslldq" 2 } } */
 /* { dg-final { scan-assembler-times "movddup" 2 } } */
-/* { dg-final { scan-assembler-times "movsd" 1 } } */
+/* { dg-final { scan-assembler-times "movsd" 2 } } */
 /* { dg-final { scan-assembler-times "movhpd" 2 } } */
 
-- 
2.51.0

Reply via email to