Make IPA-SRA follow comdat-local rules (PR 91956)
diff mbox series

Message ID ri636efhosg.fsf@suse.cz
State New
Headers show
Series
  • Make IPA-SRA follow comdat-local rules (PR 91956)
Related show

Commit Message

Martin Jambor Nov. 22, 2019, 4:13 p.m. UTC
Hi,

this verifier error happens because first IPA-split splits a comdat
function creating a comdat local callee and then IPA-SRA comes along,
modifies the caller, makes it a local clone in the process but because
it does not set the comdat group to the original, the verifier sees a
call from outside of the comdat group to a private comdat symbol, which
it does not like.

Fixed by doing what IPA-split does in the patch below.  Bootstrapped and
tested on x86_64-linux.  OK for trunk?

Thanks,

Martin


2019-11-21  Martin Jambor  <mjambor@suse.cz>

	PR ipa/91956
	* ipa-sra.c (process_isra_node_results): Put the new node to the
	same comdat group as the original node.

	testsuite/
	* g++.dg/ipa/pr91956.C: New test.
---
 gcc/ipa-sra.c                      |  3 +++
 gcc/testsuite/g++.dg/ipa/pr91956.C | 27 +++++++++++++++++++++++++++
 2 files changed, 30 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ipa/pr91956.C

Comments

Jan Hubicka Nov. 22, 2019, 5 p.m. UTC | #1
> Hi,
> 
> this verifier error happens because first IPA-split splits a comdat
> function creating a comdat local callee and then IPA-SRA comes along,
> modifies the caller, makes it a local clone in the process but because
> it does not set the comdat group to the original, the verifier sees a
> call from outside of the comdat group to a private comdat symbol, which
> it does not like.
> 
> Fixed by doing what IPA-split does in the patch below.  Bootstrapped and
> tested on x86_64-linux.  OK for trunk?
> 
> Thanks,
> 
> Martin
> 
> 
> 2019-11-21  Martin Jambor  <mjambor@suse.cz>
> 
> 	PR ipa/91956
> 	* ipa-sra.c (process_isra_node_results): Put the new node to the
> 	same comdat group as the original node.
> 
> 	testsuite/
> 	* g++.dg/ipa/pr91956.C: New test.
> ---
>  gcc/ipa-sra.c                      |  3 +++
>  gcc/testsuite/g++.dg/ipa/pr91956.C | 27 +++++++++++++++++++++++++++
>  2 files changed, 30 insertions(+)
>  create mode 100644 gcc/testsuite/g++.dg/ipa/pr91956.C
> 
> diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c
> index 08606aeded1..c6ed0f44b87 100644
> --- a/gcc/ipa-sra.c
> +++ b/gcc/ipa-sra.c
> @@ -3759,6 +3759,9 @@ process_isra_node_results (cgraph_node *node,
>      = node->create_virtual_clone (callers, NULL, new_adjustments, "isra",
>  				  suffix_counter);
>    suffix_counter++;
> +  if (node->same_comdat_group)
> +    new_node->add_to_same_comdat_group (node);
> +  new_node->calls_comdat_local = node->calls_comdat_local;

This looks correct, but since I do not remember how that is done,
can you please double-check that the symbol actually gets output into
the given comdat section in the assembly file?

Honza

Patch
diff mbox series

diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c
index 08606aeded1..c6ed0f44b87 100644
--- a/gcc/ipa-sra.c
+++ b/gcc/ipa-sra.c
@@ -3759,6 +3759,9 @@  process_isra_node_results (cgraph_node *node,
     = node->create_virtual_clone (callers, NULL, new_adjustments, "isra",
 				  suffix_counter);
   suffix_counter++;
+  if (node->same_comdat_group)
+    new_node->add_to_same_comdat_group (node);
+  new_node->calls_comdat_local = node->calls_comdat_local;
 
   if (dump_file)
     fprintf (dump_file, "  Created new node %s\n", new_node->dump_name ());
diff --git a/gcc/testsuite/g++.dg/ipa/pr91956.C b/gcc/testsuite/g++.dg/ipa/pr91956.C
new file mode 100644
index 00000000000..6f6edc30a47
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr91956.C
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-options "-Os -std=c++11 -fno-strict-aliasing -fno-tree-fre -fno-tree-vrp"  } */
+
+int count = 0;
+struct VB
+{
+  VB() {++count;}
+};
+
+struct B : virtual VB
+{
+  B() : B(42) {}
+  B(int)  {}
+};
+
+struct D : B
+{
+  D() {}
+  D(int) : D() {}
+};
+
+int main()
+{
+  D d{42};
+  if (count != 1)
+    __builtin_abort();
+}