This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH, ARM] Fix unrecognizable vector comparisons


On Mon, Jul 08, 2013 at 04:32:13PM +0100, Zhenqiang Chen wrote:
> On 8 July 2013 20:57, Ramana Radhakrishnan <ramana.gcc@googlemail.com> wrote:
> > Not yet. Why is this not a problem in the LT / UNLT case ?
> 
> From the context, after the first switch, only GE/LE/EQ might have
> operands[5] which is not REG (CONST0_RTX). For others including
> LT/UNLT, operands[5] should be REG.

This is true, but looks like an omission. My copy of the ARMARM
has immediate #0 instruction forms for CMLT, CMLE, CMGE, CMGT
and CMEQ. Perhaps it is beyond the scope of your bugfix
(though it was in your original patch?), but this should be
fixed in future so as not to force 0 to registers.

> 
> if (!REG_P (operands[5]))
>   operands[5] = force_reg (<MODE>mode, operands[5]);
> 
> For GE/LE/EQ, we only reverse LE. So only LE has issue.
> 

For now, but as above - as soon as this code is fixed to generate
immediate #0 forms, it will be fragile again.

> >> diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
> >> index 2761adb..6d9f604 100644
> >> --- a/gcc/config/arm/neon.md
> >> +++ b/gcc/config/arm/neon.md
> >> @@ -1710,6 +1710,9 @@
> >>      case LE:
> >>      case UNLE:
> >>        inverse = 1;
> >> +      /* Can not inverse "a LE 0" to "0 GE a".  */
> >> +      if (operands[5] == CONST0_RTX (<MODE>mode))
> >> +       inverse = 0;
> >>        /* Fall through.  */
> >>      case GT:
> >>      case UNGT:

Is this really what you mean? Surely now you will have:

  inverse = 0
  base_comparison = gen_neon_vcgt

Thus in the next switch you will call:
  emit_insn (gen_neon_vcgt (mask, operands[4], operands[5], magic_rtx));

Which looks wrong. Would you not also have to set swap_bsl_operands
to get back to the correct semantics?

> >> diff --git a/gcc/testsuite/gcc.target/arm/lp1189445.c
> >> b/gcc/testsuite/gcc.target/arm/lp1189445.c
> >> new file mode 100644
> >> index 0000000..8ce4b97
> >> --- /dev/null
> >> +++ b/gcc/testsuite/gcc.target/arm/lp1189445.c
> >> @@ -0,0 +1,16 @@
> >> +/* { dg-do compile } */
> >> +/* { dg-options "-O3 -mfpu=neon -mcpu=cortex-a9 -mthumb
> >> -mfloat-abi=hard -S" } */
> >> +
> >> +int id;
> >> +int
> >> +test (const long int *data)
> >> +{
> >> +  int i, retval;
> >> +  retval = id;
> >> +  for (i = 0; i < id; i++)
> >> +    {
> >> +      retval &= (data[i] <= 0);
> >> +    }
> >> +
> >> +  return (retval);
> >> +}
> 

This testcase is not much use. It may well compile, but won't catch
the wrong instruction generation issue I pointed out above.

I much prefer your original patch, with a more rigorous testcase.

Thanks,
James


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]