aarch64: Fix ICE on fpsr fpcr getters [PR96968]
authorAndrea Corallo <andrea.corallo@arm.com>
Mon, 14 Sep 2020 13:47:24 +0000 (14:47 +0100)
committerAndrea Corallo <andrea.corallo@arm.com>
Mon, 21 Sep 2020 08:38:23 +0000 (10:38 +0200)
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.

gcc/config/aarch64/aarch64-builtins.c
gcc/testsuite/gcc.target/aarch64/pr96968.c [new file with mode: 0644]

index 4f33dd936c7aa54c773cca2e1d779216506fbb44..2f4753b25cc9ed8bf63a3d4a0e6b9e4f6f17b8ec 100644 (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;
diff --git a/gcc/testsuite/gcc.target/aarch64/pr96968.c b/gcc/testsuite/gcc.target/aarch64/pr96968.c
new file mode 100644 (file)
index 0000000..21ffd95
--- /dev/null
@@ -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 } } */