PR90723

Richard Sandiford richard.sandiford@arm.com
Wed Jul 10 20:23:00 GMT 2019


Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> writes:
> Hi,
> For following test-case:
>
> typedef double v4df __attribute__ ((vector_size (32)));
> void foo(v4df);
>
> int
> main ()
> {
>   volatile v4df x1;
>   x1 = (v4df) { 10.0, 20.0, 30.0, 40.0 };
>   foo (x1);
>   return 0;
> }
>
> Compiling with -msve-vector-bits=256, the compiler goes into infinite
> recursion and eventually segfaults due to stack overflow.
>
> This happens during expansion of:
>   x1.0_1 ={v} x1;
>
> aarch64_expand_sve_mem_move calls aarch64_emit_sve_pred_move with
> dest = (reg:VNx2DF 93) and
> src = (mem/u/c:VNx2DF
>            (plus:DI (reg/f:DI 94) (const_int 32 [0x20])) [0  S32 A128])
>
> aarch64_emit_sve_pred_move calls expand_insn with above ops.
> Eventually we hit EXPAND_INPUT case in maybe_legitimize_operand for
> src (opno == 2)
>
> Since the operand is marked with volatile, and volatile_ok is set to false,
> insn_operand_matches return false and we call:
>       op->value = copy_to_mode_reg (mode, op->value);
>       break;
>
> copy_to_mode_reg however, creates a fresh register and calls emit_move_insn:
> rtx temp = gen_reg_rtx (mode);
> if (x != temp)
>     emit_move_insn (temp, x);
>
> and we again end up in aarch64_emit_sve_pred_move, with dest assigned
> the new register and src remaining unchanged, and thus the cycle continues.
>
> As suggested by Richard, the attached patch temporarily sets volatile_ok to true
> using RAII class volatile_ok_temp in aarch64_emit_sve_pred_move which
> avoids the recursion.
>
> Bootstrap + tested on x86_64-unknown-linux-gnu, aarch64-linux-gnu.
> Cross-testing with SVE in progress.
> OK to commit ?
>
> Thanks,
> Prathamesh
>
> 2019-07-09  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>
>
> 	PR target/90723
> 	* recog.h (volatile_ok_temp): New class.
> 	* config/aarch64/aarch64.c (aarch64_emit_sve_pred_move): Set
> 	volatile_ok temporarily to true using volatile_ok_temp.
> 	* expr.c (emit_block_move_via_cpymem): Likewise.
> 	* optabs.c (maybe_legitimize_operand): Likewise. 

I'm the last person who should be suggesting names, but how about
temporary_volatile_ok?  Putting "temp" after the name IMO makes it
sound too much like it's describing the RAII object rather than the
value of volatile_ok itself.

> diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
> index 5a923ca006b..50afba1a2b6 100644
> --- a/gcc/config/aarch64/aarch64.c
> +++ b/gcc/config/aarch64/aarch64.c
> @@ -3457,6 +3457,7 @@ aarch64_emit_sve_pred_move (rtx dest, rtx pred, rtx src)
>    create_output_operand (&ops[0], dest, mode);
>    create_input_operand (&ops[1], pred, GET_MODE(pred));
>    create_input_operand (&ops[2], src, mode);
> +  volatile_ok_temp v(true);

Missing space before "(".  Same for later uses.

> [...]
> diff --git a/gcc/recog.h b/gcc/recog.h
> index 75cbbdc10ad..8a8eaf7e0c3 100644
> --- a/gcc/recog.h
> +++ b/gcc/recog.h
> @@ -186,6 +186,22 @@ skip_alternative (const char *p)
>  /* Nonzero means volatile operands are recognized.  */
>  extern int volatile_ok;
>  
> +/* RAII class for temporarily setting volatile_ok.  */
> +
> +class volatile_ok_temp
> +{
> +public:
> +  volatile_ok_temp(int value): save_volatile_ok (volatile_ok)

Missing space before "(" and before ":".

> +  {
> +    volatile_ok = value;
> +  }
> +
> +  ~volatile_ok_temp() { volatile_ok = save_volatile_ok; }

Missing space before "(".

> +
> +private:
> +  int save_volatile_ok;

For extra safety we should probably have a private copy constructor
(declaration only, no implementation).  We're still C++03 and so can't
use "= delete".

Thanks,
Richard


> +};
> +
>  /* Set by constrain_operands to the number of the alternative that
>     matched.  */
>  extern int which_alternative;



More information about the Gcc-patches mailing list