[PATCH] aarch64: Fix ICE on fpsr fpcr getters [PR96968]

Richard Sandiford richard.sandiford@arm.com
Wed Sep 16 11:42:20 GMT 2020


Andrea Corallo <andrea.corallo@arm.com> writes:
> @@ -2034,6 +2034,16 @@ aarch64_expand_fpsr_fpcr_setter (int unspec, machine_mode mode, tree exp)
>    emit_insn (gen_aarch64_set (unspec, mode, op));
>  }
>  
> +/* Expand a fpsr or fpcr getter (depending on UNSPEC) using MODE.
> +   Return the target.  */
> +static rtx
> +aarch64_expand_fpsr_fpcr_getter (int unspec, machine_mode mode)
> +{
> +  rtx target = gen_reg_rtx (mode);
> +  emit_insn (gen_aarch64_get (unspec, mode, target));
> +  return target;
> +}

I agree this is functionally correct, but if a valid target has
been given to the caller, it's generally better to use it.
So IMO it would be better to use the expand_insn machinery,
passing the original target to create_output_operand.

Thanks,
Richard

> +
>  /* Expand an expression EXP that calls built-in function FCODE,
>     with result going to TARGET if that's convenient.  IGNORE is true
>     if the result of the builtin is ignored.  */
> @@ -2048,26 +2058,22 @@ aarch64_general_expand_builtin (unsigned int fcode, tree exp, rtx target,
>    switch (fcode)
>      {
>      case AARCH64_BUILTIN_GET_FPCR:
> -      emit_insn (gen_aarch64_get (UNSPECV_GET_FPCR, SImode, target));
> -      return target;
> +      return aarch64_expand_fpsr_fpcr_getter (UNSPECV_GET_FPCR, SImode);
>      case AARCH64_BUILTIN_SET_FPCR:
>        aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPCR, SImode, exp);
>        return target;
>      case AARCH64_BUILTIN_GET_FPSR:
> -      emit_insn (gen_aarch64_get (UNSPECV_GET_FPSR, SImode, target));
> -      return target;
> +      return aarch64_expand_fpsr_fpcr_getter (UNSPECV_GET_FPSR, SImode);
>      case AARCH64_BUILTIN_SET_FPSR:
>        aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPSR, SImode, exp);
>        return target;
>      case AARCH64_BUILTIN_GET_FPCR64:
> -      emit_insn (gen_aarch64_get (UNSPECV_GET_FPCR, DImode, target));
> -      return target;
> +      return aarch64_expand_fpsr_fpcr_getter (UNSPECV_GET_FPCR, DImode);
>      case AARCH64_BUILTIN_SET_FPCR64:
>        aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPCR, DImode, exp);
>        return target;
>      case AARCH64_BUILTIN_GET_FPSR64:
> -      emit_insn (gen_aarch64_get (UNSPECV_GET_FPSR, DImode, target));
> -      return target;
> +      return aarch64_expand_fpsr_fpcr_getter (UNSPECV_GET_FPSR, DImode);
>      case AARCH64_BUILTIN_SET_FPSR64:
>        aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPSR, DImode, exp);
>        return target;
> diff --git a/gcc/testsuite/gcc.target/aarch64/pr96968.c b/gcc/testsuite/gcc.target/aarch64/pr96968.c
> new file mode 100644
> index 00000000000..21ffd955153
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/pr96968.c
> @@ -0,0 +1,28 @@
> +/* { dg-options "-O1" } */
> +
> +void
> +fpsr_getter (void)
> +{
> +  unsigned int fpsr = __builtin_aarch64_get_fpsr ();
> +}
> +
> +void
> +fpsr64_getter (void)
> +{
> +  unsigned long fpsr = __builtin_aarch64_get_fpsr64 ();
> +}
> +
> +void
> +fpcr_getter (void)
> +{
> +  unsigned int fpcr = __builtin_aarch64_get_fpcr ();
> +}
> +
> +void
> +fpcr64_getter (void)
> +{
> +  unsigned long fpcr = __builtin_aarch64_get_fpcr64 ();
> +}
> +
> +/* { dg-final { scan-assembler-times {\tmrs\tx0, fpsr\n} 2 } } */
> +/* { dg-final { scan-assembler-times {\tmrs\tx0, fpcr\n} 2 } } */


More information about the Gcc-patches mailing list