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][GCC][Arm] Fix subreg crash in different way by enabling the FP16 pattern unconditionally.


Hi Tamar,

On Mon, 23 Jul 2018 at 17:56, Tamar Christina <tamar.christina@arm.com> wrote:
>
> Hi All,
>
> My previous patch changed arm_can_change_mode_class to allow subregs of
> 64bit registers on arm big-endian.  However it seems that we can't do this
> because a the data in 64 bit VFP registers are stored in little-endian order,
> even on big-endian.
>
> Allowing this change had a knock on effect that caused GCC's no-op detection
> to think that loading from the first lane on arm big-endian is a no-op.  this
> because we can't describe the weird ordering we have on D registers on big-endian.
>
> The original issue comes from the fact that the code does
>
> ... foo (... bar)
> {
>   return bar;
> }
>
> The expansion of the return statement causes GCC to try to return the value in
> a register.  GCC will try to emit the move then, from MEM to REG (due to the SSA
> temporary.).  It checks for a mov optab for this which isn't available and
> then tries to do the move in bits using emit_move_multi_word.
>
> emit_move_multi_word will split the move into sub parts, but then needs to get
> the sub parts and does this using subregs, but it's told it can't do subregs!
>
> The compiler is now stuck in an infinite loop.
>
> The way this is worked around in the back-end is that we have move patterns in
> neon.md that usually just force the register instead of checking with the
> back-end. This prevents emit_move_multi_word from being needed.  However the
> pattern for V4HF and V8HF were guarded by TARGET_NEON && TARGET_FP16.
>
> I don't believe the TARGET_FP16 guard to be needed, because the pattern doesn't
> actually generate code and requires another pattern for that, and a reg to reg move
> should always be possible anyway. So allowing the force to register here is safe
> and it allows the compiler to generate a correct error instead of ICEing in an
> infinite loop.

How about subreg to subreg move? Doesn't that expand to more insns
(subreg to reg and reg to subreg)? Couldn't you improve the logic to
check that there is actually a mode change so that if there isn't
(like moving from one subreg to another) just expand to a single move?

Best regards,

Thomas

>
> This patch ensures gcc.target/arm/big-endian-subreg.c is fixed without introducing
> any regressions while fixing
>
> gcc.dg/vect/vect-nop-move.c execution test
> g++.dg/torture/vshuf-v2si.C   -O3 -g  execution test
> g++.dg/torture/vshuf-v4si.C   -O3 -g  execution test
> g++.dg/torture/vshuf-v8hi.C   -O3 -g  execution test
>
> Regtested on armeb-none-eabi and no regressions.
> Bootstrapped on arm-none-linux-gnueabihf and no issues.
>
>
> Ok for trunk?
>
> Thanks,
> Tamar
>
> gcc/
> 2018-07-23  Tamar Christina  <tamar.christina@arm.com>
>
>         PR target/84711
>         * config/arm/arm.c (arm_can_change_mode_class): Disallow subreg.
>         * config/arm/neon.md (movv4hf, movv8hf): Refactored to..
>         (mov<mov>): ..this and enable unconditionally.
>
> --


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