[AArch64] Fix ICES with -mgeneral-regs-only / -march=...+nofp
authorAlan Lawrence <alan.lawrence@arm.com>
Wed, 24 Jun 2015 16:13:28 +0000 (16:13 +0000)
committerAlan Lawrence <alalaw01@gcc.gnu.org>
Wed, 24 Jun 2015 16:13:28 +0000 (16:13 +0000)
gcc/ChangeLog:

* config/aarch64/aarch64-protos.h (aarch64_err_no_fpadvsimd): New.

* config/aarch64/aarch64.md (mov<mode>/GPF, movtf): Use
aarch64_err_no_fpadvsimd.

* config/aarch64/aarch64.c (aarch64_err_no_fpadvsimd): New.
(aarch64_layout_arg, aarch64_init_cumulative_args): Use
aarch64_err_no_fpadvsimd if !TARGET_FLOAT and we need FP regs.
(aarch64_expand_builtin_va_start, aarch64_setup_incoming_varargs):
Turn error into assert, test TARGET_FLOAT.
(aarch64_gimplify_va_arg_expr): Use aarch64_err_no_fpadvsimd, test
TARGET_FLOAT.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/mgeneral-regs_1.c: New file.
* gcc.target/aarch64/mgeneral-regs_2.c: New file.
* gcc.target/aarch64/nofp_1.c: New file.

From-SVN: r224908

gcc/ChangeLog
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/mgeneral-regs_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/mgeneral-regs_2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/nofp_1.c [new file with mode: 0644]

index 40e73c910826f0b60c824d4e02594196e32787ae..dc609a91f31b62abc4cfe8d100209cf5ea7c569b 100644 (file)
@@ -1,3 +1,18 @@
+2015-06-24  Alan Lawrence  <alan.lawrence@arm.com>
+
+       * config/aarch64/aarch64-protos.h (aarch64_err_no_fpadvsimd): New.
+
+       * config/aarch64/aarch64.md (mov<mode>/GPF, movtf): Use
+       aarch64_err_no_fpadvsimd.
+
+       * config/aarch64/aarch64.c (aarch64_err_no_fpadvsimd): New.
+       (aarch64_layout_arg, aarch64_init_cumulative_args): Use
+       aarch64_err_no_fpadvsimd if !TARGET_FLOAT and we need FP regs.
+       (aarch64_expand_builtin_va_start, aarch64_setup_incoming_varargs):
+       Turn error into assert, test TARGET_FLOAT.
+       (aarch64_gimplify_va_arg_expr): Use aarch64_err_no_fpadvsimd, test
+       TARGET_FLOAT.
+
 2015-06-24  Aldy Hernandez  <aldyh@redhat.com>
 
        PR debug/66482
index 965a11b7beeaaaa188819796e2b17017a87dca80..ac92c5924a4cfc5941fe8eeb31281e18bd21a5a0 100644 (file)
@@ -259,6 +259,7 @@ unsigned aarch64_dbx_register_number (unsigned);
 unsigned aarch64_trampoline_size (void);
 void aarch64_asm_output_labelref (FILE *, const char *);
 void aarch64_elf_asm_named_section (const char *, unsigned, tree);
+void aarch64_err_no_fpadvsimd (machine_mode, const char *);
 void aarch64_expand_epilogue (bool);
 void aarch64_expand_mov_immediate (rtx, rtx);
 void aarch64_expand_prologue (void);
index 17bae0870c3bd210aea0b77a4069f6e207fb0c4e..fa1f7da3954326aa7b9bd7590a4e82f94b46f5e6 100644 (file)
@@ -520,6 +520,16 @@ static const char * const aarch64_condition_codes[] =
   "hi", "ls", "ge", "lt", "gt", "le", "al", "nv"
 };
 
+void
+aarch64_err_no_fpadvsimd (machine_mode mode, const char *msg)
+{
+  const char *mc = FLOAT_MODE_P (mode) ? "floating-point" : "vector";
+  if (TARGET_GENERAL_REGS_ONLY)
+    error ("%qs is incompatible with %s %s", "-mgeneral-regs-only", mc, msg);
+  else
+    error ("%qs feature modifier is incompatible with %s %s", "+nofp", mc, msg);
+}
+
 static unsigned int
 aarch64_min_divisions_for_recip_mul (enum machine_mode mode)
 {
@@ -1770,6 +1780,9 @@ aarch64_layout_arg (cumulative_args_t pcum_v, machine_mode mode,
      and homogenous short-vector aggregates (HVA).  */
   if (allocate_nvrn)
     {
+      if (!TARGET_FLOAT)
+       aarch64_err_no_fpadvsimd (mode, "argument");
+
       if (nvrn + nregs <= NUM_FP_ARG_REGS)
        {
          pcum->aapcs_nextnvrn = nvrn + nregs;
@@ -1896,6 +1909,17 @@ aarch64_init_cumulative_args (CUMULATIVE_ARGS *pcum,
   pcum->aapcs_stack_words = 0;
   pcum->aapcs_stack_size = 0;
 
+  if (!TARGET_FLOAT
+      && fndecl && TREE_PUBLIC (fndecl)
+      && fntype && fntype != error_mark_node)
+    {
+      const_tree type = TREE_TYPE (fntype);
+      machine_mode mode ATTRIBUTE_UNUSED; /* To pass pointer as argument.  */
+      int nregs ATTRIBUTE_UNUSED; /* Likewise.  */
+      if (aarch64_vfp_is_call_or_return_candidate (TYPE_MODE (type), type,
+                                                  &mode, &nregs, NULL))
+       aarch64_err_no_fpadvsimd (TYPE_MODE (type), "return type");
+    }
   return;
 }
 
@@ -7555,9 +7579,7 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
 
   if (!TARGET_FLOAT)
     {
-      if (cum->aapcs_nvrn > 0)
-       sorry ("%qs and floating point or vector arguments",
-              "-mgeneral-regs-only");
+      gcc_assert (cum->aapcs_nvrn == 0);
       vr_save_area_size = 0;
     }
 
@@ -7664,8 +7686,7 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
     {
       /* TYPE passed in fp/simd registers.  */
       if (!TARGET_FLOAT)
-       sorry ("%qs and floating point or vector arguments",
-              "-mgeneral-regs-only");
+       aarch64_err_no_fpadvsimd (mode, "varargs");
 
       f_top = build3 (COMPONENT_REF, TREE_TYPE (f_vrtop),
                      unshare_expr (valist), f_vrtop, NULL_TREE);
@@ -7902,9 +7923,7 @@ aarch64_setup_incoming_varargs (cumulative_args_t cum_v, machine_mode mode,
 
   if (!TARGET_FLOAT)
     {
-      if (local_cum.aapcs_nvrn > 0)
-       sorry ("%qs and floating point or vector arguments",
-              "-mgeneral-regs-only");
+      gcc_assert (local_cum.aapcs_nvrn == 0);
       vr_saved = 0;
     }
 
index d3f5d5b20632b412d028416591ca7c449d885e08..934c8faf6d6ecd90a21fbc3243b8b79ab328177c 100644 (file)
   [(set (match_operand:GPF 0 "nonimmediate_operand" "")
        (match_operand:GPF 1 "general_operand" ""))]
   ""
-  "
+  {
     if (!TARGET_FLOAT)
-     {
-       sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
+      {
+       aarch64_err_no_fpadvsimd (<MODE>mode, "code");
        FAIL;
-     }
+      }
 
     if (GET_CODE (operands[0]) == MEM
         && ! (GET_CODE (operands[1]) == CONST_DOUBLE
              && aarch64_float_const_zero_rtx_p (operands[1])))
       operands[1] = force_reg (<MODE>mode, operands[1]);
-  "
+  }
 )
 
 (define_insn "*movsf_aarch64"
   [(set (match_operand:TF 0 "nonimmediate_operand" "")
        (match_operand:TF 1 "general_operand" ""))]
   ""
-  "
+  {
     if (!TARGET_FLOAT)
-     {
-       sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
+      {
+       aarch64_err_no_fpadvsimd (TFmode, "code");
        FAIL;
-     }
+      }
 
     if (GET_CODE (operands[0]) == MEM
         && ! (GET_CODE (operands[1]) == CONST_DOUBLE
              && aarch64_float_const_zero_rtx_p (operands[1])))
       operands[1] = force_reg (TFmode, operands[1]);
-  "
+  }
 )
 
 (define_insn "*movtf_aarch64"
index 26d39ce9afd93be53776a8977b673b6432fd9ffd..b9084a6e393ad753790879a404720426304f0506 100644 (file)
@@ -1,3 +1,9 @@
+2015-06-24  Alan Lawrence  <alan.lawrence@arm.com>
+
+       * gcc.target/aarch64/mgeneral-regs_1.c: New file.
+       * gcc.target/aarch64/mgeneral-regs_2.c: New file.
+       * gcc.target/aarch64/nofp_1.c: New file.
+
 2015-06-24  Edward Smith-Rowland  <3dw4rd@verizon.net>
 
        Implement N3928 - Extending static_assert
diff --git a/gcc/testsuite/gcc.target/aarch64/mgeneral-regs_1.c b/gcc/testsuite/gcc.target/aarch64/mgeneral-regs_1.c
new file mode 100644 (file)
index 0000000..b5192a6
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-options "-mgeneral-regs-only" } */
+
+typedef int int32x2_t __attribute__ ((__vector_size__ ((8))));
+
+/* { dg-error "'-mgeneral-regs-only' is incompatible with vector return type" "" {target "aarch64*-*-*"} 7 } */
+/* { dg-error "'-mgeneral-regs-only' is incompatible with vector argument" "" {target "aarch64*-*-*"} 7 } */
+int32x2_t test (int32x2_t a, int32x2_t b)
+{
+  return a + b;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/mgeneral-regs_2.c b/gcc/testsuite/gcc.target/aarch64/mgeneral-regs_2.c
new file mode 100644 (file)
index 0000000..8590199
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-options "-mgeneral-regs-only" } */
+
+#include <stdarg.h>
+
+typedef int int32x2_t __attribute__ ((__vector_size__ ((8))));
+
+int
+test (int i, ...)
+{
+  va_list argp;
+  va_start (argp, i);
+  int32x2_t x = (int32x2_t) {0, 1};
+  x += va_arg (argp, int32x2_t); /* { dg-error "'-mgeneral-regs-only' is incompatible with vector varargs" } */
+  return x[0] + x[1];
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/nofp_1.c b/gcc/testsuite/gcc.target/aarch64/nofp_1.c
new file mode 100644 (file)
index 0000000..3fc0036
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-skip-if "conflicting -march" { *-*-* } { "-march=*" } { "-march=*+nofp" } } */
+/* If there are multiple -march's, the latest wins; skip the test either way.
+   -march overrides -mcpu, so there is no possibility of conflict.  */
+
+/* { dg-options "-march=armv8-a+nofp" } */
+
+#include <stdarg.h>
+
+typedef int int32x2_t __attribute__ ((__vector_size__ ((8))));
+
+int test (int i, ...);
+
+int
+main (int argc, char **argv)
+{
+  int32x2_t a = (int32x2_t) {0, 1};
+  int32x2_t b = (int32x2_t) {2, 3};
+  return test (2, a, b); /* { dg-error "'\\+nofp' feature modifier is incompatible with vector argument" } */
+}