aarch64: Fix ICE on fpsr fpcr getters [PR96968]

gcc/ChangeLog

2020-09-14  Andrea Corallo  <andrea.corallo@arm.com>

	PR target/96968
	* config/aarch64/aarch64-builtins.c
	(aarch64_expand_fpsr_fpcr_setter): Fix comment nit.
	(aarch64_expand_fpsr_fpcr_getter): New function, expand these
	getters using expand_insn machinery.
	(aarch64_general_expand_builtin): Make use of.

gcc/testsuite/ChangeLog

2020-09-14  Andrea Corallo  <andrea.corallo@arm.com>

	PR target/96968
	* gcc.target/aarch64/pr96968.c: New test.
This commit is contained in:
Andrea Corallo 2020-09-14 14:47:24 +01:00
parent da87190421
commit f5e73de00e
2 changed files with 49 additions and 9 deletions

View file

@ -2024,7 +2024,7 @@ aarch64_expand_builtin_memtag (int fcode, tree exp, rtx target)
return target;
}
/* Expand an expression EXP as fpsr or cpsr setter (depending on
/* Expand an expression EXP as fpsr or fpcr setter (depending on
UNSPEC) using MODE. */
static void
aarch64_expand_fpsr_fpcr_setter (int unspec, machine_mode mode, tree exp)
@ -2034,6 +2034,18 @@ 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 (enum insn_code icode, machine_mode mode,
rtx target)
{
expand_operand op;
create_output_operand (&op, target, mode);
expand_insn (icode, 1, &op);
return op.value;
}
/* 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 +2060,26 @@ 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 (CODE_FOR_aarch64_get_fpcrsi,
SImode, target);
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 (CODE_FOR_aarch64_get_fpsrsi,
SImode, target);
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 (CODE_FOR_aarch64_get_fpcrdi,
DImode, target);
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 (CODE_FOR_aarch64_get_fpsrdi,
DImode, target);
case AARCH64_BUILTIN_SET_FPSR64:
aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPSR, DImode, exp);
return target;

View file

@ -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 } } */