public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-7768] [PR99581] Define relaxed memory and use it for aarch64
@ 2021-03-22 17:37 Vladimir Makarov
  0 siblings, 0 replies; only message in thread
From: Vladimir Makarov @ 2021-03-22 17:37 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:02f2dc441b1954736cc61e3f97687cd23d5586c5

commit r11-7768-g02f2dc441b1954736cc61e3f97687cd23d5586c5
Author: Vladimir N. Makarov <vmakarov@redhat.com>
Date:   Mon Mar 22 13:34:50 2021 -0400

    [PR99581] Define relaxed memory and use it for aarch64
    
    aarch64 needs to skip memory address validation for LD1R insns.  Skipping
    the address validation may result in LRA crash for some targets when usual
    memory constraint is used.  This patch introduces define_relaxed_memory_constraint,
    skipping address validation for it, and defining relaxed memory for
    aarch64 LD1r insn memory operand.
    
    gcc/ChangeLog:
    
            PR target/99581
            * config/aarch64/constraints.md (UtQ): Use
            define_relaxed_memory_constraint for it.
            * doc/md.texi (define_relaxed_memory_constraint): Describe it.
            * genoutput.c (main): Process DEFINE_RELAXED_MEMORY_CONSTRAINT.
            * genpreds.c (constraint_data): Add bitfield is_relaxed_memory.
            (have_relaxed_memory_constraints): New static var.
            (relaxed_memory_start, relaxed_memory_end): Ditto.
            (add_constraint): Add arg is_relaxed_memory.  Check name for
            relaxed memory.  Set up is_relaxed_memory in constraint_data and
            have_relaxed_memory_constraints.  Adjust calls.
            (choose_enum_order): Process relaxed memory.
            (write_tm_preds_h): Ditto.
            (main): Process DEFINE_RELAXED_MEMORY_CONSTRAINT.
            * gensupport.c (process_rtx): Process DEFINE_RELAXED_MEMORY_CONSTRAINT.
            * ira-costs.c (record_reg_classes): Process CT_RELAXED_MEMORY.
            * ira-lives.c (single_reg_class): Use
            insn_extra_relaxed_memory_constraint.
            * ira.c (ira_setup_alts): CT_RELAXED_MEMORY.
            * lra-constraints.c (valid_address_p): Use
            insn_extra_relaxed_memory_constraint instead of other memory
            constraints.
            (process_alt_operands): Process CT_RELAXED_MEMORY.
            (curr_insn_transform): Use insn_extra_relaxed_memory_constraint.
            * recog.c (asm_operand_ok, preprocess_constraints): Process
            CT_RELAXED_MEMORY.
            * reload.c (find_reloads): Ditto.
            * rtl.def (DEFINE_RELAXED_MEMORY_CONSTRAINT): New.
            * stmt.c (parse_input_constraint): Use
            insn_extra_relaxed_memory_constraint.
    
    gcc/testsuite/ChangeLog:
    
            PR target/99581
            * gcc.target/powerpc/pr99581.c: New.

Diff:
---
 gcc/config/aarch64/constraints.md          |  2 +-
 gcc/doc/md.texi                            | 28 ++++++++++-
 gcc/genoutput.c                            |  1 +
 gcc/genpreds.c                             | 75 +++++++++++++++++-------------
 gcc/gensupport.c                           |  1 +
 gcc/ira-costs.c                            |  1 +
 gcc/ira-lives.c                            |  1 +
 gcc/ira.c                                  |  1 +
 gcc/lra-constraints.c                      |  7 +--
 gcc/recog.c                                |  2 +
 gcc/reload.c                               |  1 +
 gcc/rtl.def                                |  1 +
 gcc/stmt.c                                 |  3 +-
 gcc/testsuite/gcc.target/powerpc/pr99581.c | 17 +++++++
 14 files changed, 102 insertions(+), 39 deletions(-)

diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md
index 09c2b7283e3..f08eea8bcae 100644
--- a/gcc/config/aarch64/constraints.md
+++ b/gcc/config/aarch64/constraints.md
@@ -330,7 +330,7 @@
        (match_test "aarch64_legitimate_address_p (V2DImode,
 						  XEXP (op, 0), 1)")))
 
-(define_memory_constraint "UtQ"
+(define_relaxed_memory_constraint "UtQ"
   "@internal
    An address valid for SVE LD1RQs."
   (and (match_code "mem")
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index e3686dbfe61..d166a0debed 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -4564,7 +4564,33 @@ specifically aligned memory is necessary or desirable for some insn
 operand.
 
 The syntax and semantics are otherwise identical to
-@code{define_constraint}.
+@code{define_memory_constraint}.
+@end deffn
+
+@deffn {MD Expression} define_relaxed_memory_constraint name docstring exp
+The test expression in a @code{define_memory_constraint} can assume
+that @code{TARGET_LEGITIMATE_ADDRESS_P} holds for the address inside
+a @code{mem} rtx and so it does not need to test this condition itself.
+In other words, a @code{define_memory_constraint} test of the form:
+
+@smallexample
+(match_test "mem")
+@end smallexample
+
+is enough to test whether an rtx is a @code{mem} @emph{and} whether
+its address satisfies @code{TARGET_MEM_CONSTRAINT} (which is usually
+@samp{'m'}).  Thus the conditions imposed by a @code{define_memory_constraint}
+always apply on top of the conditions imposed by @code{TARGET_MEM_CONSTRAINT}.
+
+However, it is sometimes useful to define memory constraints that allow
+addresses beyond those accepted by @code{TARGET_LEGITIMATE_ADDRESS_P}.
+@code{define_relaxed_memory_constraint} exists for this case.
+The test expression in a @code{define_relaxed_memory_constraint} is
+applied with no preconditions, so that the expression can determine
+``from scratch'' exactly which addresses are valid and which are not.
+
+The syntax and semantics are otherwise identical to
+@code{define_memory_constraint}.
 @end deffn
 
 @deffn {MD Expression} define_address_constraint name docstring exp
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index b88e13b90b6..25af4375d9c 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -1024,6 +1024,7 @@ main (int argc, const char **argv)
       case DEFINE_ADDRESS_CONSTRAINT:
       case DEFINE_MEMORY_CONSTRAINT:
       case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
+      case DEFINE_RELAXED_MEMORY_CONSTRAINT:
 	note_constraint (&info);
 	break;
 
diff --git a/gcc/genpreds.c b/gcc/genpreds.c
index 8499a2a2383..63fac0c7d34 100644
--- a/gcc/genpreds.c
+++ b/gcc/genpreds.c
@@ -660,9 +660,9 @@ write_one_predicate_function (struct pred_data *p)
 /* Constraints fall into two categories: register constraints
    (define_register_constraint), and others (define_constraint,
    define_memory_constraint, define_special_memory_constraint,
-   define_address_constraint).  We work out automatically which of the
-   various old-style macros they correspond to, and produce
-   appropriate code.  They all go in the same hash table so we can
+   define_relaxed_memory_constraint, define_address_constraint).  We work out
+   automatically which of the various old-style macros they correspond to, and
+   produce appropriate code.  They all go in the same hash table so we can
    verify that there are no duplicate names.  */
 
 /* All data from one constraint definition.  */
@@ -683,6 +683,7 @@ public:
   unsigned int is_extra		: 1;
   unsigned int is_memory	: 1;
   unsigned int is_special_memory: 1;
+  unsigned int is_relaxed_memory: 1;
   unsigned int is_address	: 1;
   unsigned int maybe_allows_reg : 1;
   unsigned int maybe_allows_mem : 1;
@@ -721,6 +722,7 @@ static unsigned int constraint_max_namelen;
 static bool have_register_constraints;
 static bool have_memory_constraints;
 static bool have_special_memory_constraints;
+static bool have_relaxed_memory_constraints;
 static bool have_address_constraints;
 static bool have_extra_constraints;
 static bool have_const_int_constraints;
@@ -732,6 +734,7 @@ static unsigned int satisfied_start;
 static unsigned int const_int_start, const_int_end;
 static unsigned int memory_start, memory_end;
 static unsigned int special_memory_start, special_memory_end;
+static unsigned int relaxed_memory_start, relaxed_memory_end;
 static unsigned int address_start, address_end;
 static unsigned int maybe_allows_none_start, maybe_allows_none_end;
 static unsigned int maybe_allows_reg_start, maybe_allows_reg_end;
@@ -756,16 +759,16 @@ mangle (const char *name)
   return XOBFINISH (rtl_obstack, const char *);
 }
 
-/* Add one constraint, of any sort, to the tables.  NAME is its name;
-   REGCLASS is the register class, if any; EXP is the expression to
-   test, if any; IS_MEMORY, IS_SPECIAL_MEMORY and IS_ADDRESS indicate
-   memory, special memory, and address constraints, respectively; LOC
-   is the .md file location.
+/* Add one constraint, of any sort, to the tables.  NAME is its name; REGCLASS
+   is the register class, if any; EXP is the expression to test, if any;
+   IS_MEMORY, IS_SPECIAL_MEMORY, IS_RELAXED_MEMORY and IS_ADDRESS indicate
+   memory, special memory, and address constraints, respectively; LOC is the .md
+   file location.
 
-   Not all combinations of arguments are valid; most importantly,
-   REGCLASS is mutually exclusive with EXP, and
-   IS_MEMORY/IS_SPECIAL_MEMORY/IS_ADDRESS are only meaningful for
-   constraints with EXP.
+   Not all combinations of arguments are valid; most importantly, REGCLASS is
+   mutually exclusive with EXP, and
+   IS_MEMORY/IS_SPECIAL_MEMORY/IS_RELAXED_MEMORY/IS_ADDRESS are only meaningful
+   for constraints with EXP.
 
    This function enforces all syntactic and semantic rules about what
    constraints can be defined.  */
@@ -773,7 +776,7 @@ mangle (const char *name)
 static void
 add_constraint (const char *name, const char *regclass,
 		rtx exp, bool is_memory, bool is_special_memory,
-		bool is_address, file_location loc)
+		bool is_relaxed_memory, bool is_address, file_location loc)
 {
   class constraint_data *c, **iter, **slot;
   const char *p;
@@ -873,7 +876,7 @@ add_constraint (const char *name, const char *regclass,
 	  return;
 	}
 
-      if (is_memory)
+      if (is_memory || is_special_memory || is_relaxed_memory)
 	{
 	  if (name[1] == '\0')
 	    error_at (loc, "constraint letter '%c' cannot be a "
@@ -884,17 +887,6 @@ add_constraint (const char *name, const char *regclass,
 		      name, name[0]);
 	  return;
 	}
-      else if (is_special_memory)
-	{
-	  if (name[1] == '\0')
-	    error_at (loc, "constraint letter '%c' cannot be a "
-		      "special memory constraint", name[0]);
-	  else
-	    error_at (loc, "constraint name '%s' begins with '%c', "
-		      "and therefore cannot be a special memory constraint",
-		      name, name[0]);
-	  return;
-	}
       else if (is_address)
 	{
 	  if (name[1] == '\0')
@@ -922,6 +914,7 @@ add_constraint (const char *name, const char *regclass,
   c->is_extra = !(regclass || is_const_int || is_const_dbl);
   c->is_memory = is_memory;
   c->is_special_memory = is_special_memory;
+  c->is_relaxed_memory = is_relaxed_memory;
   c->is_address = is_address;
   c->maybe_allows_reg = true;
   c->maybe_allows_mem = true;
@@ -949,19 +942,21 @@ add_constraint (const char *name, const char *regclass,
   have_extra_constraints |= c->is_extra;
   have_memory_constraints |= c->is_memory;
   have_special_memory_constraints |= c->is_special_memory;
+  have_relaxed_memory_constraints |= c->is_relaxed_memory;
   have_address_constraints |= c->is_address;
   num_constraints += 1;
 }
 
 /* Process a DEFINE_CONSTRAINT, DEFINE_MEMORY_CONSTRAINT,
-   DEFINE_SPECIAL_MEMORY_CONSTRAINT, or DEFINE_ADDRESS_CONSTRAINT
-   expression, C.  */
+   DEFINE_SPECIAL_MEMORY_CONSTRAINT, DEFINE_RELAXED_MEMORY_CONSTRAINT, or
+   DEFINE_ADDRESS_CONSTRAINT expression, C.  */
 static void
 process_define_constraint (md_rtx_info *info)
 {
   add_constraint (XSTR (info->def, 0), 0, XEXP (info->def, 2),
 		  GET_CODE (info->def) == DEFINE_MEMORY_CONSTRAINT,
 		  GET_CODE (info->def) == DEFINE_SPECIAL_MEMORY_CONSTRAINT,
+		  GET_CODE (info->def) == DEFINE_RELAXED_MEMORY_CONSTRAINT,
 		  GET_CODE (info->def) == DEFINE_ADDRESS_CONSTRAINT,
 		  info->loc);
 }
@@ -971,7 +966,7 @@ static void
 process_define_register_constraint (md_rtx_info *info)
 {
   add_constraint (XSTR (info->def, 0), XSTR (info->def, 1),
-		  0, false, false, false, info->loc);
+		  0, false, false, false, false, info->loc);
 }
 
 /* Put the constraints into enum order.  We want to keep constraints
@@ -1011,6 +1006,12 @@ choose_enum_order (void)
       enum_order[next++] = c;
   special_memory_end = next;
 
+  relaxed_memory_start = next;
+  FOR_ALL_CONSTRAINTS (c)
+    if (c->is_relaxed_memory)
+      enum_order[next++] = c;
+  relaxed_memory_end = next;
+
   address_start = next;
   FOR_ALL_CONSTRAINTS (c)
     if (c->is_address)
@@ -1020,7 +1021,7 @@ choose_enum_order (void)
   maybe_allows_none_start = next;
   FOR_ALL_CONSTRAINTS (c)
     if (!c->is_register && !c->is_const_int && !c->is_memory
-	&& !c->is_special_memory && !c->is_address
+	&& !c->is_special_memory && !c->is_relaxed_memory && !c->is_address
 	&& !c->maybe_allows_reg && !c->maybe_allows_mem)
       enum_order[next++] = c;
   maybe_allows_none_end = next;
@@ -1028,7 +1029,7 @@ choose_enum_order (void)
   maybe_allows_reg_start = next;
   FOR_ALL_CONSTRAINTS (c)
     if (!c->is_register && !c->is_const_int && !c->is_memory
-	&& !c->is_special_memory && !c->is_address
+	&& !c->is_special_memory && !c->is_relaxed_memory && !c->is_address
 	&& c->maybe_allows_reg && !c->maybe_allows_mem)
       enum_order[next++] = c;
   maybe_allows_reg_end = next;
@@ -1036,14 +1037,14 @@ choose_enum_order (void)
   maybe_allows_mem_start = next;
   FOR_ALL_CONSTRAINTS (c)
     if (!c->is_register && !c->is_const_int && !c->is_memory
-	&& !c->is_special_memory && !c->is_address
+	&& !c->is_special_memory && !c->is_relaxed_memory && !c->is_address
 	&& !c->maybe_allows_reg && c->maybe_allows_mem)
       enum_order[next++] = c;
   maybe_allows_mem_end = next;
 
   FOR_ALL_CONSTRAINTS (c)
     if (!c->is_register && !c->is_const_int && !c->is_memory
-	&& !c->is_special_memory && !c->is_address
+	&& !c->is_special_memory && !c->is_relaxed_memory && !c->is_address
 	&& c->maybe_allows_reg && c->maybe_allows_mem)
       enum_order[next++] = c;
   gcc_assert (next == num_constraints);
@@ -1466,6 +1467,8 @@ write_tm_preds_h (void)
 			    memory_start, memory_end);
       write_range_function ("insn_extra_special_memory_constraint",
 			    special_memory_start, special_memory_end);
+      write_range_function ("insn_extra_relaxed_memory_constraint",
+			    relaxed_memory_start, relaxed_memory_end);
       write_range_function ("insn_extra_address_constraint",
 			    address_start, address_end);
       write_allows_reg_mem_function ();
@@ -1515,6 +1518,7 @@ write_tm_preds_h (void)
 	    "  CT_CONST_INT,\n"
 	    "  CT_MEMORY,\n"
 	    "  CT_SPECIAL_MEMORY,\n"
+	    "  CT_RELAXED_MEMORY,\n"
 	    "  CT_ADDRESS,\n"
 	    "  CT_FIXED_FORM\n"
 	    "};\n"
@@ -1528,7 +1532,11 @@ write_tm_preds_h (void)
       if (memory_start != memory_end)
 	values.safe_push (std::make_pair (memory_start, "CT_MEMORY"));
       if (special_memory_start != special_memory_end)
-	values.safe_push (std::make_pair (special_memory_start, "CT_SPECIAL_MEMORY"));
+	values.safe_push (std::make_pair (special_memory_start,
+					  "CT_SPECIAL_MEMORY"));
+      if (relaxed_memory_start != relaxed_memory_end)
+	values.safe_push (std::make_pair (relaxed_memory_start,
+					  "CT_RELAXED_MEMORY"));
       if (address_start != address_end)
 	values.safe_push (std::make_pair (address_start, "CT_ADDRESS"));
       if (address_end != num_constraints)
@@ -1645,6 +1653,7 @@ main (int argc, const char **argv)
       case DEFINE_CONSTRAINT:
       case DEFINE_MEMORY_CONSTRAINT:
       case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
+      case DEFINE_RELAXED_MEMORY_CONSTRAINT:
       case DEFINE_ADDRESS_CONSTRAINT:
 	process_define_constraint (&info);
 	break;
diff --git a/gcc/gensupport.c b/gcc/gensupport.c
index fdf4a9fdc1f..0f19bd70664 100644
--- a/gcc/gensupport.c
+++ b/gcc/gensupport.c
@@ -582,6 +582,7 @@ process_rtx (rtx desc, file_location loc)
     case DEFINE_REGISTER_CONSTRAINT:
     case DEFINE_MEMORY_CONSTRAINT:
     case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
+    case DEFINE_RELAXED_MEMORY_CONSTRAINT:
     case DEFINE_ADDRESS_CONSTRAINT:
       queue_pattern (desc, &define_pred_tail, loc);
       break;
diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c
index cf1d4992927..7547f3e0f53 100644
--- a/gcc/ira-costs.c
+++ b/gcc/ira-costs.c
@@ -780,6 +780,7 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
 		      break;
 
 		    case CT_SPECIAL_MEMORY:
+		    case CT_RELAXED_MEMORY:
 		      insn_allows_mem[i] = allows_mem[i] = 1;
 		      if (MEM_P (extract_mem_from_operand (op))
 			  && constraint_satisfied_p (op, cn))
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index f3341313bd1..bd1818bb255 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -872,6 +872,7 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
 	    cn = lookup_constraint (constraints);
 	    if (insn_extra_memory_constraint (cn)
 		|| insn_extra_special_memory_constraint (cn)
+		|| insn_extra_relaxed_memory_constraint (cn)
 		|| insn_extra_address_constraint (cn))
 	      return NO_REGS;
 	    if (constraint_satisfied_p (op, cn)
diff --git a/gcc/ira.c b/gcc/ira.c
index fc77131491d..7e903289e79 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -1874,6 +1874,7 @@ ira_setup_alts (rtx_insn *insn)
 			  mem = op;
 			  /* Fall through.  */
 			case CT_SPECIAL_MEMORY:
+			case CT_RELAXED_MEMORY:
 			  if (!mem)
 			    mem = extract_mem_from_operand (op);
 			  if (MEM_P (mem))
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index fdfe953bcf5..861b5aad40b 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -410,8 +410,7 @@ valid_address_p (rtx op, struct address_info *ad,
      Need to extract memory from op for special memory constraint,
      i.e. bcst_mem_operand in i386 backend.  */
   if (MEM_P (extract_mem_from_operand (op))
-      && (insn_extra_memory_constraint (constraint)
-	  || insn_extra_special_memory_constraint (constraint))
+      && insn_extra_relaxed_memory_constraint (constraint)
       && constraint_satisfied_p (op, constraint))
     return true;
 
@@ -2460,6 +2459,7 @@ process_alt_operands (int only_alternative)
 		      break;
 
 		    case CT_SPECIAL_MEMORY:
+		    case CT_RELAXED_MEMORY:
 		      if (satisfies_memory_constraint_p (op, cn))
 			win = true;
 		      else if (spilled_pseudo_p (op))
@@ -4370,7 +4370,8 @@ curr_insn_transform (bool check_only_p)
 	      {
 		enum constraint_num cn = lookup_constraint (constraint);
 		if ((insn_extra_memory_constraint (cn)
-		     || insn_extra_special_memory_constraint (cn))
+		     || insn_extra_special_memory_constraint (cn)
+		     || insn_extra_relaxed_memory_constraint (cn))
 		    && satisfies_memory_constraint_p (tem, cn))
 		  break;
 	      }
diff --git a/gcc/recog.c b/gcc/recog.c
index abbc49f3f9b..ee143bc761e 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -2270,6 +2270,7 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints)
 	      mem = op;
 	      /* Fall through.  */
 	    case CT_SPECIAL_MEMORY:
+	    case CT_RELAXED_MEMORY:
 	      /* Every memory operand can be reloaded to fit.  */
 	      if (!mem)
 		mem = extract_mem_from_operand (op);
@@ -2892,6 +2893,7 @@ preprocess_constraints (int n_operands, int n_alternatives,
 
 		    case CT_MEMORY:
 		    case CT_SPECIAL_MEMORY:
+		    case CT_RELAXED_MEMORY:
 		      op_alt[i].memory_ok = 1;
 		      break;
 
diff --git a/gcc/reload.c b/gcc/reload.c
index c88f928392b..7340125c441 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -3504,6 +3504,7 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
 			break;
 
 		      case CT_SPECIAL_MEMORY:
+		      case CT_RELAXED_MEMORY:
 			if (force_reload)
 			  break;
 			if (constraint_satisfied_p (operand, cn))
diff --git a/gcc/rtl.def b/gcc/rtl.def
index 92b3de822be..b85eb5c0055 100644
--- a/gcc/rtl.def
+++ b/gcc/rtl.def
@@ -1055,6 +1055,7 @@ DEF_RTL_EXPR(DEFINE_REGISTER_CONSTRAINT, "define_register_constraint", "sss", RT
 DEF_RTL_EXPR(DEFINE_CONSTRAINT, "define_constraint", "sse", RTX_EXTRA)
 DEF_RTL_EXPR(DEFINE_MEMORY_CONSTRAINT, "define_memory_constraint", "sse", RTX_EXTRA)
 DEF_RTL_EXPR(DEFINE_SPECIAL_MEMORY_CONSTRAINT, "define_special_memory_constraint", "sse", RTX_EXTRA)
+DEF_RTL_EXPR(DEFINE_RELAXED_MEMORY_CONSTRAINT, "define_relaxed_memory_constraint", "sse", RTX_EXTRA)
 DEF_RTL_EXPR(DEFINE_ADDRESS_CONSTRAINT, "define_address_constraint", "sse", RTX_EXTRA)
 
 
diff --git a/gcc/stmt.c b/gcc/stmt.c
index f52ffaf8e75..297e0d0ff5d 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -419,7 +419,8 @@ parse_input_constraint (const char **constraint_p, int input_num,
 	    || insn_extra_address_constraint (cn))
 	  *allows_reg = true;
 	else if (insn_extra_memory_constraint (cn)
-		 || insn_extra_special_memory_constraint (cn))
+		 || insn_extra_special_memory_constraint (cn)
+		 || insn_extra_relaxed_memory_constraint (cn))
 	  *allows_mem = true;
 	else
 	  insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
diff --git a/gcc/testsuite/gcc.target/powerpc/pr99581.c b/gcc/testsuite/gcc.target/powerpc/pr99581.c
new file mode 100644
index 00000000000..525f2762773
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr99581.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+char e[37540];
+struct A { int c; } d;
+
+void
+bar (int n)
+{
+  __asm__("" : : "r" (e));
+}
+
+void
+foo (void)
+{
+  __asm__("stw %1, %0" : "=o" (d.c) : "r" (0));
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-03-22 17:37 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-22 17:37 [gcc r11-7768] [PR99581] Define relaxed memory and use it for aarch64 Vladimir Makarov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).