diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 64801b6fcce..698d8d04a1e 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -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 diff --git a/gcc/testsuite/gcc.target/s390/pr99663.c b/gcc/testsuite/gcc.target/s390/pr99663.c new file mode 100644 index 00000000000..f4f0f94a63a --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr99663.c @@ -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; +}