aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor L. Do Nascimento <victor.donascimento@arm.com>2023-04-18 17:11:58 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2023-04-18 17:11:58 +0100
commitb80317116547c85c176a7e41bdb67376cee6f0ce (patch)
tree342964f5a29efaa574fe38a73fbb05d9cf0dcc7b
parentb7c54e3f48086c29179f7765a35c381de5109a0a (diff)
downloadgcc-b80317116547c85c176a7e41bdb67376cee6f0ce.zip
gcc-b80317116547c85c176a7e41bdb67376cee6f0ce.tar.gz
gcc-b80317116547c85c176a7e41bdb67376cee6f0ce.tar.bz2
constraint: fix relaxed memory and repeated constraint handling
The function `constrain_operands' lacked the logic to consider relaxed memory constraints when "traditional" memory constraints were not satisfied, creating potential issues as observed during the reload compilation pass. In addition, it was observed that while `constrain_operands' chooses to disregard constraints when more than one alternative is provided, e.g. "m,r" using CONSTRAINT__UNKNOWN, it has no checks in place to determine whether the multiple constraints in a given string are in fact repetitions of the same constraint and should thus in fact be treated as a single constraint, as ought to be the case for something like "m,m". Both of these issues are dealt with here, thus ensuring that we get appropriate pattern matching. gcc/ * lra-constraints.cc (constraint_unique): New. (process_address_1): Apply constraint_unique test. * recog.cc (constrain_operands): Allow relaxed memory constaints.
-rw-r--r--gcc/lra-constraints.cc39
-rw-r--r--gcc/recog.cc3
2 files changed, 38 insertions, 4 deletions
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index ff4e8f0..b231cb6 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -3450,6 +3450,41 @@ skip_constraint_modifiers (const char *str)
}
}
+/* Takes a string of 0 or more comma-separated constraints. When more
+ than one constraint is present, evaluate whether they all correspond
+ to a single, repeated constraint (e.g. "r,r") or whether we have
+ more than one distinct constraints (e.g. "r,m"). */
+static bool
+constraint_unique (const char *cstr)
+{
+ enum constraint_num ca, cb;
+ ca = CONSTRAINT__UNKNOWN;
+ for (;;)
+ {
+ cstr = skip_constraint_modifiers (cstr);
+ if (*cstr == '\0' || *cstr == ',')
+ cb = CONSTRAINT_X;
+ else
+ {
+ cb = lookup_constraint (cstr);
+ if (cb == CONSTRAINT__UNKNOWN)
+ return false;
+ cstr += CONSTRAINT_LEN (cstr[0], cstr);
+ }
+ /* Handle the first iteration of the loop. */
+ if (ca == CONSTRAINT__UNKNOWN)
+ ca = cb;
+ /* Handle the general case of comparing ca with subsequent
+ constraints. */
+ else if (ca != cb)
+ return false;
+ if (*cstr == '\0')
+ return true;
+ if (*cstr == ',')
+ cstr += 1;
+ }
+}
+
/* Major function to make reloads for an address in operand NOP or
check its correctness (If CHECK_ONLY_P is true). The supported
cases are:
@@ -3509,9 +3544,7 @@ process_address_1 (int nop, bool check_only_p,
operand has one address constraint, probably all others constraints are
address ones. */
if (constraint[0] != '\0' && get_constraint_type (cn) != CT_ADDRESS
- && *skip_constraint_modifiers (constraint
- + CONSTRAINT_LEN (constraint[0],
- constraint)) != '\0')
+ && !constraint_unique (constraint))
cn = CONSTRAINT__UNKNOWN;
if (insn_extra_address_constraint (cn)
/* When we find an asm operand with an address constraint that
diff --git a/gcc/recog.cc b/gcc/recog.cc
index 200cf42..3ddeab5 100644
--- a/gcc/recog.cc
+++ b/gcc/recog.cc
@@ -3234,7 +3234,8 @@ constrain_operands (int strict, alternative_mask alternatives)
else if (constraint_satisfied_p (op, cn))
win = 1;
- else if (insn_extra_memory_constraint (cn)
+ else if ((insn_extra_memory_constraint (cn)
+ || insn_extra_relaxed_memory_constraint (cn))
/* Every memory operand can be reloaded to fit. */
&& ((strict < 0 && MEM_P (op))
/* Before reload, accept what reload can turn