Hi,

Consider this openmp example:
...
/* { dg-do link } */

#define N 100

int
main ()
{
  int a[N];
  int i, x;
  int c;

  c = 1;
#pragma omp target
  for (i = 0; i < 100; i++)
    a[i] = 0;

  if (c)
    __builtin_unreachable ();

#pragma omp target
  for (i = 0; i < 100; i++)
    a[i] = 1;

  return 0;
}
...

At ompexp, there are two offloaded functions, main._omp_fn.0 and main._omp_fn.1:
...
  <bb 2> :
  c = 1;
  ...
  __builtin_GOMP_target_ext (-1, main._omp_fn.0, 2, &.omp_data_arr.2,
                             &.omp_data_sizes.3, &.omp_data_kinds.4,
                             0, 0B, &.omp_target_args.9);
  ...
  if (c != 0)
    goto <bb 3>; [INV]
  else
    goto <bb 4>; [INV]

  <bb 3> :
  __builtin_unreachable ();

 <bb 4> :
  ...
  __builtin_GOMP_target_ext (-1, main._omp_fn.1, 2, &.omp_data_arr.5,
                             &.omp_data_sizes.6, &.omp_data_kinds.7, 0,
                             0B, &.omp_target_args.8);
...

But after cpp1, the reference to main._omp_fn.1 in main is removed:
...
  __builtin_GOMP_target_ext (-1, main._omp_fn.0, 2, &.omp_data_arr.2,
                             &.omp_data_sizes.3, &.omp_data_kinds.4,
                             0, 0B, &.omp_target_args.9);
  __builtin_unreachable ();
...
Consequently, during free-fnsummary, the cgraph_node for main._omp_fn.1 is removed.

However, the main._omp_fn.1 function is still present in the offload table offload_funcs. This causes an ICE in lto1 when we're trying access the cgraph_node* for main._omp_fn.1, which is NULL:
....
lto1: internal compiler error: Segmentation fault
0xab73cf crash_signal
        gcc/toplev.c:325
0x94f694 cgraph_node::mark_force_output()
        gcc/cgraph.h:3140
0x94dfda input_offload_tables(bool)
        gcc/lto-cgraph.c:1940
0x5aa19f read_cgraph_and_symbols
        gcc/lto/lto.c:2872
0x5aa19f lto_main()
        gcc/lto/lto.c:3323
...

The ICE can be triggered for both openmp and openacc.

This patch fixes the ICE by removing entries from offload_funcs that no longer have corresponding cgraph_nodes.

Bootstrapped and reg-tested on x86_64.
Build and reg-tested on x86_64 with nvptx accelerator.

OK for trunk?

Thanks,
- Tom
Prune removed funcs from offload table

2017-12-27  Tom de Vries  <t...@codesourcery.com>

	PR libgomp/83046
	* lto-cgraph.c (output_offload_tables): Remove offload_funcs entries
	that no longer have a corresponding cgraph_node.

	* testsuite/libgomp.oacc-c-c++-common/pr83046.c: New test.
	* testsuite/libgomp.c-c++-common/pr83046.c: New test.

---
 gcc/lto-cgraph.c                                   | 10 +++++++++
 libgomp/testsuite/libgomp.c-c++-common/pr83046.c   | 25 ++++++++++++++++++++++
 .../testsuite/libgomp.oacc-c-c++-common/pr83046.c  | 25 ++++++++++++++++++++++
 3 files changed, 60 insertions(+)

diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index ed3df15b143..6bef2d974a6 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -1111,6 +1111,16 @@ output_offload_tables (void)
   struct lto_simple_output_block *ob
     = lto_create_simple_output_block (LTO_section_offload_table);
 
+  for (unsigned i = 0; i < vec_safe_length (offload_funcs);)
+    {
+      if (!cgraph_node::get ((*offload_funcs)[i]))
+	{
+	  offload_funcs->ordered_remove (i);
+	  continue;
+	}
+      i++;
+    }
+
   for (unsigned i = 0; i < vec_safe_length (offload_funcs); i++)
     {
       streamer_write_enum (ob->main_stream, LTO_symtab_tags,
diff --git a/libgomp/testsuite/libgomp.c-c++-common/pr83046.c b/libgomp/testsuite/libgomp.c-c++-common/pr83046.c
new file mode 100644
index 00000000000..90dcb704fb3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/pr83046.c
@@ -0,0 +1,25 @@
+/* { dg-do link } */
+
+#define N 100
+
+int
+main ()
+{
+  int a[N];
+  int i, x;
+  int c;
+
+  c = 1;
+#pragma omp target
+  for (i = 0; i < 100; i++)
+    a[i] = 0;
+
+  if (c)
+    __builtin_unreachable ();
+
+#pragma omp target
+  for (i = 0; i < 100; i++)
+    a[i] = 1;
+
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr83046.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr83046.c
new file mode 100644
index 00000000000..a2a085c5fb2
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr83046.c
@@ -0,0 +1,25 @@
+/* { dg-do link } */
+
+#define N 100
+
+int
+main ()
+{
+  int a[N];
+  int i, x;
+  int c;
+
+  c = 1;
+#pragma acc parallel loop
+  for (i = 0; i < 100; i++)
+    a[i] = 0;
+
+  if (c)
+    __builtin_unreachable ();
+
+#pragma acc parallel loop
+  for (i = 0; i < 100; i++)
+    a[i] = 1;
+
+  return 0;
+}

Reply via email to