[PR99663] Don't use unknown constraint for address constraint in process_address_1.

s390x has insns using several alternatives with address constraints.  Even
if we don't know at this stage what alternative will be used, we still can say
that is an address constraint.  So don't use unknown constraint in this
case when there are multiple constraints or/and alternative.

gcc/ChangeLog:

	PR target/99663
	* lra-constraints.c (process_address_1): Don't use unknown
	constraint for address constraint.

gcc/testsuite/ChangeLog:

	PR target/99663
	* gcc.target/s390/pr99663.c: New.
This commit is contained in:
Vladimir N. Makarov 2021-03-19 15:34:48 -04:00
parent 82bb66730b
commit d81019db09
2 changed files with 30 additions and 5 deletions

View File

@ -3459,12 +3459,17 @@ process_address_1 (int nop, bool check_only_p,
constraint
= skip_contraint_modifiers (curr_static_id->operand[dup].constraint);
}
if (*skip_contraint_modifiers (constraint
+ CONSTRAINT_LEN (constraint[0],
constraint)) != '\0')
cn = lookup_constraint (*constraint == '\0' ? "X" : constraint);
/* If we have several alternatives or/and several constraints in an
alternative and we can not say at this stage what constraint will be used,
use unknown constraint. The exception is an address constraint. If
operand has one address constraint, probably all others constraints are
address ones. */
if (get_constraint_type (cn) != CT_ADDRESS
&& *skip_contraint_modifiers (constraint
+ CONSTRAINT_LEN (constraint[0],
constraint)) != '\0')
cn = CONSTRAINT__UNKNOWN;
else
cn = lookup_constraint (*constraint == '\0' ? "X" : constraint);
if (insn_extra_address_constraint (cn)
/* When we find an asm operand with an address constraint that
doesn't satisfy address_operand to begin with, we clear

View File

@ -0,0 +1,20 @@
/* { dg-do compile } */
/* { dg-options "-mtune=z15 -march=z13 -mzarch -O2 -fno-stack-protector -fPIC" } */
typedef struct {
int exponent;
unsigned short lsu[];
} decNumber;
decNumber decDivideOp_lhs;
short decDivideOp_varbuff;
void decDivideOp(decNumber *rhs) {
short *msu1;
int exponent;
unsigned short *source;
for (; source >= decDivideOp_lhs.lsu; source--, msu1--)
*msu1 = *source;
for (;;)
if (exponent)
if (decDivideOp_varbuff)
exponent = rhs->exponent;
}