On Thu, Dec 31, 2020 at 7:57 AM Richard Sandiford via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > aarch64's *add<mode>3_poly_1 has a pattern with the constraints: > > "=...,r,&r" > "...,0,rk" > "...,Uai,Uat" > > i.e. the penultimate alternative requires operands 0 and 1 to match, > but the final alternative does not allow them to match. > > The register allocators dealt with this correctly, and so used > different input and output registers for instructions with Uat > operands. However, constrain_operands carried the penultimate > alternative's matching rule over to the final alternative, > so it would essentially ignore the earlyclobber. This in turn > allowed postreload to convert a correct Uat pairing into an > incorrect one. > > The fix is simple: recompute the matching information for each > alternative. > > Tested on aarch64-linux-gnu, aarch64_be-elf and x86_64-linux-gnu. > OK to install? > > Richard > > > gcc/ > PR rtl-optimization/97144 > * recog.c (constrain_operands): Initialize matching_operand > for each alternative, rather than only doing it once. > > gcc/testsuite/ > PR rtl-optimization/97144 > * gcc.target/aarch64/sve/pr97144.c: New test. > --- > gcc/recog.c | 8 +++--- > .../gcc.target/aarch64/sve/pr97144.c | 26 +++++++++++++++++++ > 2 files changed, 30 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/pr97144.c > > diff --git a/gcc/recog.c b/gcc/recog.c > index e9aa1ba253d..29d6c491e15 100644 > --- a/gcc/recog.c > +++ b/gcc/recog.c > @@ -3022,10 +3022,7 @@ constrain_operands (int strict, alternative_mask > alternatives) > return 1; > > for (c = 0; c < recog_data.n_operands; c++) > - { > - constraints[c] = recog_data.constraints[c]; > - matching_operands[c] = -1; > - } > + constraints[c] = recog_data.constraints[c]; > > do > { > @@ -3045,6 +3042,9 @@ constrain_operands (int strict, alternative_mask > alternatives) > continue; > } > > + for (opno = 0; opno < recog_data.n_operands; opno++) > + matching_operands[opno] = -1; > + > for (opno = 0; opno < recog_data.n_operands; opno++) > { > rtx op = recog_data.operand[opno]; > diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr97144.c > b/gcc/testsuite/gcc.target/aarch64/sve/pr97144.c > new file mode 100644 > index 00000000000..75245e2350b > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/sve/pr97144.c > @@ -0,0 +1,26 @@ > +/* { dg-options "-O2 -ftree-vectorize" } */ > + > +int a, b = 5, c = 3; > +char d; > +char e[1]; > +int f[] = {0, 0, 1}; > +short g; > +char *h = e; > +void i(void) { b = a; } > +static void j(void) { > + h = e; > + if (f[2]) > + k: > + for (;;) { > + for (c = 0; c <= 4; c++) { > + for (g = 0; g <= 4; g++) > + f[g + 4] &= 2; > + } > + if (d) > + goto k; > + } > +} > +void l(void) { > + j(); > + c = 0; > +}
Is this test specific to aarch64? -- H.J.