LRA: handle memory constraints that accept more than "m"
authorRichard Sandiford <richard.sandiford@arm.com>
Mon, 18 Nov 2019 15:26:07 +0000 (15:26 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 18 Nov 2019 15:26:07 +0000 (15:26 +0000)
LRA allows address constraints that are more relaxed than "p":

  /* Target hooks sometimes don't treat extra-constraint addresses as
     legitimate address_operands, so handle them specially.  */
  if (insn_extra_address_constraint (cn)
      && satisfies_address_constraint_p (&ad, cn))
    return change_p;

For SVE it's useful to allow the same thing for memory constraints.
The particular use case is LD1RQ, which is an SVE instruction that
addresses Advanced SIMD vector modes and that accepts some addresses
that normal Advanced SIMD moves don't.

Normally we require every memory to satisfy at least "m", which is
defined to be a memory "with any kind of address that the machine
supports in general".  However, LD1RQ is very much special-purpose:
it doesn't really have any relation to normal operations on these
modes.  Adding its addressing modes to "m" would lead to bad Advanced
SIMD optimisation decisions in passes like ivopts.  LD1RQ therefore
has a memory constraint that accepts things "m" doesn't.

2019-11-18  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* lra-constraints.c (valid_address_p): Take the operand and a
constraint as argument.  If the operand is a MEM and the constraint
is a memory constraint, check whether the eliminated form of the
MEM already satisfies the constraint.
(process_address_1): Update calls accordingly.

gcc/testsuite/
* gcc.target/aarch64/sve/acle/asm/ld1rq_f16.c: Remove XFAIL.
* gcc.target/aarch64/sve/acle/asm/ld1rq_f32.c: Likewise.
* gcc.target/aarch64/sve/acle/asm/ld1rq_f64.c: Likewise.
* gcc.target/aarch64/sve/acle/asm/ld1rq_s16.c: Likewise.
* gcc.target/aarch64/sve/acle/asm/ld1rq_s32.c: Likewise.
* gcc.target/aarch64/sve/acle/asm/ld1rq_s64.c: Likewise.
* gcc.target/aarch64/sve/acle/asm/ld1rq_u16.c: Likewise.
* gcc.target/aarch64/sve/acle/asm/ld1rq_u32.c: Likewise.
* gcc.target/aarch64/sve/acle/asm/ld1rq_u64.c: Likewise.

From-SVN: r278408

12 files changed:
gcc/ChangeLog
gcc/lra-constraints.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/sve/acle/asm/ld1rq_f16.c
gcc/testsuite/gcc.target/aarch64/sve/acle/asm/ld1rq_f32.c
gcc/testsuite/gcc.target/aarch64/sve/acle/asm/ld1rq_f64.c
gcc/testsuite/gcc.target/aarch64/sve/acle/asm/ld1rq_s16.c
gcc/testsuite/gcc.target/aarch64/sve/acle/asm/ld1rq_s32.c
gcc/testsuite/gcc.target/aarch64/sve/acle/asm/ld1rq_s64.c
gcc/testsuite/gcc.target/aarch64/sve/acle/asm/ld1rq_u16.c
gcc/testsuite/gcc.target/aarch64/sve/acle/asm/ld1rq_u32.c
gcc/testsuite/gcc.target/aarch64/sve/acle/asm/ld1rq_u64.c

index 6dbe6856472ce8a80236cbeac01e8099a4992979..eac041016acdd6828efbaa975632d9a0bfbccaeb 100644 (file)
@@ -1,3 +1,11 @@
+2019-11-18  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * lra-constraints.c (valid_address_p): Take the operand and a
+       constraint as argument.  If the operand is a MEM and the constraint
+       is a memory constraint, check whether the eliminated form of the
+       MEM already satisfies the constraint.
+       (process_address_1): Update calls accordingly.
+
 2019-11-18  Tom Tromey  <tromey@adacore.com>
 
        * doc/tm.texi: Rebuild.
index 54b5ae5cffed9bbf0a58f0a46f2d8e1c6b0092b4..39d2d2c54210f0b9b9f88d3ebc838a1379f54ff5 100644 (file)
@@ -388,11 +388,24 @@ address_eliminator::~address_eliminator ()
     *m_index_loc = m_index_reg;
 }
 
-/* Return true if the eliminated form of AD is a legitimate target address.  */
+/* Return true if the eliminated form of AD is a legitimate target address.
+   If OP is a MEM, AD is the address within OP, otherwise OP should be
+   ignored.  CONSTRAINT is one constraint that the operand may need
+   to meet.  */
 static bool
-valid_address_p (struct address_info *ad)
+valid_address_p (rtx op, struct address_info *ad,
+                enum constraint_num constraint)
 {
   address_eliminator eliminator (ad);
+
+  /* Allow a memory OP if it matches CONSTRAINT, even if CONSTRAINT is more
+     forgiving than "m".  */
+  if (MEM_P (op)
+      && (insn_extra_memory_constraint (constraint)
+         || insn_extra_special_memory_constraint (constraint))
+      && constraint_satisfied_p (op, constraint))
+    return true;
+
   return valid_address_p (ad->mode, *ad->outer, ad->as);
 }
 
@@ -3397,7 +3410,7 @@ process_address_1 (int nop, bool check_only_p,
 
      All these cases involve a non-autoinc address, so there is no
      point revalidating other types.  */
-  if (ad.autoinc_p || valid_address_p (&ad))
+  if (ad.autoinc_p || valid_address_p (op, &ad, cn))
     return change_p;
 
   /* Any index existed before LRA started, so we can assume that the
@@ -3426,7 +3439,7 @@ process_address_1 (int nop, bool check_only_p,
              if (code >= 0)
                {
                  *ad.inner = gen_rtx_LO_SUM (Pmode, new_reg, addr);
-                 if (! valid_address_p (ad.mode, *ad.outer, ad.as))
+                 if (!valid_address_p (op, &ad, cn))
                    {
                      /* Try to put lo_sum into register.  */
                      insn = emit_insn (gen_rtx_SET
@@ -3436,7 +3449,7 @@ process_address_1 (int nop, bool check_only_p,
                      if (code >= 0)
                        {
                          *ad.inner = new_reg;
-                         if (! valid_address_p (ad.mode, *ad.outer, ad.as))
+                         if (!valid_address_p (op, &ad, cn))
                            {
                              *ad.inner = addr;
                              code = -1;
@@ -3531,7 +3544,7 @@ process_address_1 (int nop, bool check_only_p,
          && CONSTANT_P (XEXP (SET_SRC (set), 1)))
        {
          *ad.inner = SET_SRC (set);
-         if (valid_address_p (ad.mode, *ad.outer, ad.as))
+         if (valid_address_p (op, &ad, cn))
            {
              *ad.base_term = XEXP (SET_SRC (set), 0);
              *ad.disp_term = XEXP (SET_SRC (set), 1);
index 5053583d14939a955bdc4431690625b8ed007e87..163ea21842f43173a73aaa0606a96c1afa633b4b 100644 (file)
@@ -1,3 +1,15 @@
+2019-11-18  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * gcc.target/aarch64/sve/acle/asm/ld1rq_f16.c: Remove XFAIL.
+       * gcc.target/aarch64/sve/acle/asm/ld1rq_f32.c: Likewise.
+       * gcc.target/aarch64/sve/acle/asm/ld1rq_f64.c: Likewise.
+       * gcc.target/aarch64/sve/acle/asm/ld1rq_s16.c: Likewise.
+       * gcc.target/aarch64/sve/acle/asm/ld1rq_s32.c: Likewise.
+       * gcc.target/aarch64/sve/acle/asm/ld1rq_s64.c: Likewise.
+       * gcc.target/aarch64/sve/acle/asm/ld1rq_u16.c: Likewise.
+       * gcc.target/aarch64/sve/acle/asm/ld1rq_u32.c: Likewise.
+       * gcc.target/aarch64/sve/acle/asm/ld1rq_u64.c: Likewise.
+
 2019-11-18  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/92516
index 4071b6d1ba38fafd148f5b342d8f611c2837e48f..b98a381fd1b515298a71a7d31641bb1433669141 100644 (file)
@@ -12,7 +12,7 @@ TEST_LOAD (ld1rq_f16_base, svfloat16_t, float16_t,
           z0 = svld1rq (p0, x0))
 
 /*
-** ld1rq_f16_index: { xfail *-*-* }
+** ld1rq_f16_index:
 **     ld1rqh  z0\.h, p0/z, \[x0, x1, lsl 1\]
 **     ret
 */
index 25013fcf0c58fd278a0999f5d1cd4f6809c47fbe..1845aa81d71782746eacfbb00058c3c96410f57b 100644 (file)
@@ -12,7 +12,7 @@ TEST_LOAD (ld1rq_f32_base, svfloat32_t, float32_t,
           z0 = svld1rq (p0, x0))
 
 /*
-** ld1rq_f32_index: { xfail *-*-* }
+** ld1rq_f32_index:
 **     ld1rqw  z0\.s, p0/z, \[x0, x1, lsl 2\]
 **     ret
 */
index 49f8da0803f0ec1c2c40e4798cd861a4d366d475..c88f3bd23ae27b15cf9108e237036cfd39ba1bb0 100644 (file)
@@ -12,7 +12,7 @@ TEST_LOAD (ld1rq_f64_base, svfloat64_t, float64_t,
           z0 = svld1rq (p0, x0))
 
 /*
-** ld1rq_f64_index: { xfail *-*-* }
+** ld1rq_f64_index:
 **     ld1rqd  z0\.d, p0/z, \[x0, x1, lsl 3\]
 **     ret
 */
index c12b659c20e2a0165f9494c6f359bb149a47d5e6..bfbbff95fbd267eda8ba4e8f7d67a07919c10530 100644 (file)
@@ -12,7 +12,7 @@ TEST_LOAD (ld1rq_s16_base, svint16_t, int16_t,
           z0 = svld1rq (p0, x0))
 
 /*
-** ld1rq_s16_index: { xfail *-*-* }
+** ld1rq_s16_index:
 **     ld1rqh  z0\.h, p0/z, \[x0, x1, lsl 1\]
 **     ret
 */
index 8184ab8001150ceacb2887675598670ffdd846bf..d31225c7e7dc1465b18ef6582372a40a9283dd31 100644 (file)
@@ -12,7 +12,7 @@ TEST_LOAD (ld1rq_s32_base, svint32_t, int32_t,
           z0 = svld1rq (p0, x0))
 
 /*
-** ld1rq_s32_index: { xfail *-*-* }
+** ld1rq_s32_index:
 **     ld1rqw  z0\.s, p0/z, \[x0, x1, lsl 2\]
 **     ret
 */
index 616ce0bfa809937197b85acfabbc74a12c345b5b..c87486dfd8070062d1c9905ab13ea756290d0c2b 100644 (file)
@@ -12,7 +12,7 @@ TEST_LOAD (ld1rq_s64_base, svint64_t, int64_t,
           z0 = svld1rq (p0, x0))
 
 /*
-** ld1rq_s64_index: { xfail *-*-* }
+** ld1rq_s64_index:
 **     ld1rqd  z0\.d, p0/z, \[x0, x1, lsl 3\]
 **     ret
 */
index 1f543006c386884a16b386bf21e3cb26a2d031f1..f7bd44802366cfcd9259419e8bba673fe2d1f138 100644 (file)
@@ -12,7 +12,7 @@ TEST_LOAD (ld1rq_u16_base, svuint16_t, uint16_t,
           z0 = svld1rq (p0, x0))
 
 /*
-** ld1rq_u16_index: { xfail *-*-* }
+** ld1rq_u16_index:
 **     ld1rqh  z0\.h, p0/z, \[x0, x1, lsl 1\]
 **     ret
 */
index e2a348d00acffd9985da28a26fdb6f36ad247db5..d815c483f94e5d69b2c302f50058d6e399fc2619 100644 (file)
@@ -12,7 +12,7 @@ TEST_LOAD (ld1rq_u32_base, svuint32_t, uint32_t,
           z0 = svld1rq (p0, x0))
 
 /*
-** ld1rq_u32_index: { xfail *-*-* }
+** ld1rq_u32_index:
 **     ld1rqw  z0\.s, p0/z, \[x0, x1, lsl 2\]
 **     ret
 */
index bf9d72016771820198bb6f8781e26f6fc6db2ff6..ef7b61aa54ec91128b49d86d8264cd601ff44172 100644 (file)
@@ -12,7 +12,7 @@ TEST_LOAD (ld1rq_u64_base, svuint64_t, uint64_t,
           z0 = svld1rq (p0, x0))
 
 /*
-** ld1rq_u64_index: { xfail *-*-* }
+** ld1rq_u64_index:
 **     ld1rqd  z0\.d, p0/z, \[x0, x1, lsl 3\]
 **     ret
 */