nvptx: Fix ICE in nvptx_vector_alignment on gcc.dg/attr-vector_size.c
authorRoger Sayle <roger@nextmovesoftware.com>
Fri, 3 Jul 2020 08:57:39 +0000 (10:57 +0200)
committerTom de Vries <tdevries@suse.de>
Fri, 3 Jul 2020 08:57:39 +0000 (10:57 +0200)
This patch addresses the ICE in gcc.dg/attr-vector_size.c during
make -k check on nvptx-none.  The actual ICE looks like:

testsuite/gcc.dg/attr-vector_size.c:29:1: internal compiler error: \
  in tree_to_shwi, at tree.c:7321
0xf53bf2 tree_to_shwi(tree_node const*)
../../gcc/gcc/tree.c:7321
0xff1969 nvptx_vector_alignment
../../gcc/gcc/config/nvptx/nvptx.c:5105^M

The problem is that the caller has ensured that TYPE_SIZE(type) is
representable as an unsigned HOST_WIDE_INT, but nvptx_vector_alignment is
accessing it as a signed HOST_WIDE_INT which overflows in pathological
conditions.  Amongst those pathological conditions is that a TYPE_SIZE of
zero can sometimes reach this function, prior to an error being emitted.
Making sure the result is not less than the mode's alignment and not greater
than BIGGEST_ALIGNMENT fixes the ICEs, and generates the expected
compile-time error messages.

Tested on --target=nvptx-none, with a "make" and "make check" which results
in four fewer unexpected failures and three more expected passes.

2020-07-03  Roger Sayle  <roger@nextmovesoftware.com>
    Tom de Vries  <tdevries@suse.de>

gcc/ChangeLog:

PR target/90932
* config/nvptx/nvptx.c (nvptx_vector_alignment): Use tree_to_uhwi
to access TYPE_SIZE (type).  Return at least the mode's alignment.

gcc/config/nvptx/nvptx.c

index e3e84dfd4e41329cfc40abce1e71946bfadde71b..d2f321fcbcc975ab91b557abea4192b80d9c935b 100644 (file)
@@ -5102,9 +5102,22 @@ static const struct attribute_spec nvptx_attribute_table[] =
 static HOST_WIDE_INT
 nvptx_vector_alignment (const_tree type)
 {
-  HOST_WIDE_INT align = tree_to_shwi (TYPE_SIZE (type));
+  unsigned HOST_WIDE_INT align;
+  tree size = TYPE_SIZE (type);
+
+  /* Ensure align is not bigger than BIGGEST_ALIGNMENT.  */
+  if (tree_fits_uhwi_p (size))
+    {
+      align = tree_to_uhwi (size);
+      align = MIN (align, BIGGEST_ALIGNMENT);
+    }
+  else
+    align = BIGGEST_ALIGNMENT;
+
+  /* Ensure align is not smaller than mode alignment.  */
+  align = MAX (align, GET_MODE_ALIGNMENT (TYPE_MODE (type)));
 
-  return MIN (align, BIGGEST_ALIGNMENT);
+  return align;
 }
 
 /* Indicate that INSN cannot be duplicated.   */