Patchwork Fix PR tree-optimization/47420

login
register
mail settings
Submitter Eric Botcazou
Date Feb. 11, 2011, 9:49 a.m.
Message ID <201102111049.05138.ebotcazou@adacore.com>
Download mbox | patch
Permalink /patch/82726/
State New
Headers show

Comments

Eric Botcazou - Feb. 11, 2011, 9:49 a.m.
Hi,

this is an ICE at -O2 on i686-pc-mingw32 caused by partial inlining.

We start with:

<L0>:
  MEM[(struct sfTextCtrlBase *)this_1(D)].D.1899.D.1763._vptr.fooControlBase = 
&_ZTV14sfTextCtrlBase[2];
  MEM[(struct sfTextCtrlBase *)this_1(D)].D.1900._vptr.sfTextAreaBase = 
&_ZTV14sfTextCtrlBase[6];
  MEM[(struct sfTextCtrlBase *)this_1(D)].D.1901.D.1826._vptr.sfTextEntryBase 
= &_ZTV14sfTextCtrlBase[10];
  D.2174_11 = this_1(D) + 8;
  MEM[(struct sfTextEntry *)this_1(D) + 8B].D.1826._vptr.sfTextEntryBase = 
&_ZTV11sfTextEntry[2];
  sfTextEntryBase::~sfTextEntryBase (D.2174_11);

[...]

<L5>:
  MEM[(struct sfTextAreaBase *)this_1(D) + 4B]._vptr.sfTextAreaBase = 
&_ZTV14sfTextAreaBase[2];

<L6>:
  resx 5

<L7>:
  MEM[(struct fooControl *)this_1(D)].D.1763._vptr.fooControlBase = 
&_ZTV10fooControl[2];
  fooControlBase::~fooControlBase (this_1(D));

<L8>:
  resx 4


L5/L6 is the cleanup of the L0 block.  Partial inlining splits at L5:

<L0>:
  MEM[(struct sfTextCtrlBase *)this_1(D)].D.1899.D.1763._vptr.fooControlBase = 
&_ZTV14sfTextCtrlBase[2];
  MEM[(struct sfTextCtrlBase *)this_1(D)].D.1900._vptr.sfTextAreaBase = 
&_ZTV14sfTextCtrlBase[6];
  MEM[(struct sfTextCtrlBase *)this_1(D)].D.1901.D.1826._vptr.sfTextEntryBase 
= &_ZTV14sfTextCtrlBase[10];
  D.2174_11 = this_1(D) + 8;
  MEM[(struct sfTextEntry *)this_1(D) + 8B].D.1826._vptr.sfTextEntryBase = 
&_ZTV11sfTextEntry[2];
  sfTextEntryBase::~sfTextEntryBase (D.2174_11);

[...]

<L5>:
  sfTextCtrl::sfTextCtrl (this_1(D));


with the split up part:

sfTextCtrl::sfTextCtrl() (struct sfTextCtrl * const this)
{
  struct sfTextCtrlBase * D.2188;
  struct sfTextEntry * D.2187;
  void * parent;

<bb 6>:

<L0>:
  MEM[(struct sfTextAreaBase *)this_1(D) + 4B]._vptr.sfTextAreaBase = 
&_ZTV14sfTextAreaBase[2];

Invalid sum of outgoing probabilities 0.0%
<L1>:
  resx 3

<L2>:
  MEM[(struct fooControl *)this_1(D)].D.1763._vptr.fooControlBase = 
&_ZTV10fooControl[2];
  fooControlBase::~fooControlBase (this_1(D));

<L3>:
  resx 2

}


Then the split up part is inlined back into the original function:

<L2>:
  MEM[(struct sfTextCtrlBase *)D.2028_1].D.1899.D.1763._vptr.fooControlBase = 
&_ZTV14sfTextCtrlBase[2];
  MEM[(struct sfTextCtrlBase *)D.2028_1].D.1900._vptr.sfTextAreaBase = 
&_ZTV14sfTextCtrlBase[6];
  MEM[(struct sfTextCtrlBase *)D.2028_1].D.1901.D.1826._vptr.sfTextEntryBase = 
&_ZTV14sfTextCtrlBase[10];
  D.2245_8 = D.2028_1 + 8;
  MEM[(struct sfTextEntry *)D.2028_1 + 8B].D.1826._vptr.sfTextEntryBase = 
&_ZTV11sfTextEntry[2];
  sfTextEntryBase::~sfTextEntryBase (D.2245_8);

[...]

<L5>:
  MEM[(struct sfTextAreaBase *)D.2028_1 + 4B]._vptr.sfTextAreaBase = 
&_ZTV14sfTextAreaBase[2];

Invalid sum of outgoing probabilities 0.0%
<L9>:
  resx 12

<L10>:
  MEM[(struct fooControl *)D.2028_1].D.1763._vptr.fooControlBase = 
&_ZTV10fooControl[2];
  fooControlBase::~fooControlBase (D.2028_1);

<L11>:
  resx 11


The problem is that the new EH regions created by inlining (11 and 12) aren't
connected with the landing pads; the landing pad of the throwing statement:

sfTextEntryBase::~sfTextEntryBase (D.2245_8);

is still connected to the original region 5.  So remove_unreachable_handlers
computes that region 12 is unreachable and turns resx 12 into a trap, which
is caught by an assertion because the successor L10 isn't reachable any more.

Partial inlining already punts on external RESXs:

      /* FIXME: We can split regions containing EH.  We can not however
	 split RESX, EH_DISPATCH and EH_POINTER referring to same region
	 into different partitions.  This would require tracking of
	 EH regions and checking in consider_split_point if they 
	 are not used elsewhere.  */
      if (gimple_code (stmt) == GIMPLE_RESX
	  && stmt_can_throw_external (stmt))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "Cannot split: external resx.\n");
	  can_split = false;
	}

but it seems to me that the "external" is bogus here, hence the proposed fix.

Tested on i586-suse-linux, OK for the mainline?


2011-02-11  Eric Botcazou  <ebotcazou@adacore.com>

	PR tree-optimization/47420
	* ipa-split.c (visit_bb): Put on any kind of GIMPLE_RESX.


2011-02-11  Eric Botcazou  <ebotcazou@adacore.com>

	* g++.dg/opt/inline17.C: New test.
Richard Guenther - Feb. 11, 2011, 10 a.m.
On Fri, Feb 11, 2011 at 10:49 AM, Eric Botcazou <ebotcazou@adacore.com> wrote:
> Hi,
>
> this is an ICE at -O2 on i686-pc-mingw32 caused by partial inlining.
>
> We start with:
>
> <L0>:
>  MEM[(struct sfTextCtrlBase *)this_1(D)].D.1899.D.1763._vptr.fooControlBase =
> &_ZTV14sfTextCtrlBase[2];
>  MEM[(struct sfTextCtrlBase *)this_1(D)].D.1900._vptr.sfTextAreaBase =
> &_ZTV14sfTextCtrlBase[6];
>  MEM[(struct sfTextCtrlBase *)this_1(D)].D.1901.D.1826._vptr.sfTextEntryBase
> = &_ZTV14sfTextCtrlBase[10];
>  D.2174_11 = this_1(D) + 8;
>  MEM[(struct sfTextEntry *)this_1(D) + 8B].D.1826._vptr.sfTextEntryBase =
> &_ZTV11sfTextEntry[2];
>  sfTextEntryBase::~sfTextEntryBase (D.2174_11);
>
> [...]
>
> <L5>:
>  MEM[(struct sfTextAreaBase *)this_1(D) + 4B]._vptr.sfTextAreaBase =
> &_ZTV14sfTextAreaBase[2];
>
> <L6>:
>  resx 5
>
> <L7>:
>  MEM[(struct fooControl *)this_1(D)].D.1763._vptr.fooControlBase =
> &_ZTV10fooControl[2];
>  fooControlBase::~fooControlBase (this_1(D));
>
> <L8>:
>  resx 4
>
>
> L5/L6 is the cleanup of the L0 block.  Partial inlining splits at L5:
>
> <L0>:
>  MEM[(struct sfTextCtrlBase *)this_1(D)].D.1899.D.1763._vptr.fooControlBase =
> &_ZTV14sfTextCtrlBase[2];
>  MEM[(struct sfTextCtrlBase *)this_1(D)].D.1900._vptr.sfTextAreaBase =
> &_ZTV14sfTextCtrlBase[6];
>  MEM[(struct sfTextCtrlBase *)this_1(D)].D.1901.D.1826._vptr.sfTextEntryBase
> = &_ZTV14sfTextCtrlBase[10];
>  D.2174_11 = this_1(D) + 8;
>  MEM[(struct sfTextEntry *)this_1(D) + 8B].D.1826._vptr.sfTextEntryBase =
> &_ZTV11sfTextEntry[2];
>  sfTextEntryBase::~sfTextEntryBase (D.2174_11);
>
> [...]
>
> <L5>:
>  sfTextCtrl::sfTextCtrl (this_1(D));
>
>
> with the split up part:
>
> sfTextCtrl::sfTextCtrl() (struct sfTextCtrl * const this)
> {
>  struct sfTextCtrlBase * D.2188;
>  struct sfTextEntry * D.2187;
>  void * parent;
>
> <bb 6>:
>
> <L0>:
>  MEM[(struct sfTextAreaBase *)this_1(D) + 4B]._vptr.sfTextAreaBase =
> &_ZTV14sfTextAreaBase[2];
>
> Invalid sum of outgoing probabilities 0.0%
> <L1>:
>  resx 3
>
> <L2>:
>  MEM[(struct fooControl *)this_1(D)].D.1763._vptr.fooControlBase =
> &_ZTV10fooControl[2];
>  fooControlBase::~fooControlBase (this_1(D));
>
> <L3>:
>  resx 2
>
> }
>
>
> Then the split up part is inlined back into the original function:
>
> <L2>:
>  MEM[(struct sfTextCtrlBase *)D.2028_1].D.1899.D.1763._vptr.fooControlBase =
> &_ZTV14sfTextCtrlBase[2];
>  MEM[(struct sfTextCtrlBase *)D.2028_1].D.1900._vptr.sfTextAreaBase =
> &_ZTV14sfTextCtrlBase[6];
>  MEM[(struct sfTextCtrlBase *)D.2028_1].D.1901.D.1826._vptr.sfTextEntryBase =
> &_ZTV14sfTextCtrlBase[10];
>  D.2245_8 = D.2028_1 + 8;
>  MEM[(struct sfTextEntry *)D.2028_1 + 8B].D.1826._vptr.sfTextEntryBase =
> &_ZTV11sfTextEntry[2];
>  sfTextEntryBase::~sfTextEntryBase (D.2245_8);
>
> [...]
>
> <L5>:
>  MEM[(struct sfTextAreaBase *)D.2028_1 + 4B]._vptr.sfTextAreaBase =
> &_ZTV14sfTextAreaBase[2];
>
> Invalid sum of outgoing probabilities 0.0%
> <L9>:
>  resx 12
>
> <L10>:
>  MEM[(struct fooControl *)D.2028_1].D.1763._vptr.fooControlBase =
> &_ZTV10fooControl[2];
>  fooControlBase::~fooControlBase (D.2028_1);
>
> <L11>:
>  resx 11
>
>
> The problem is that the new EH regions created by inlining (11 and 12) aren't
> connected with the landing pads; the landing pad of the throwing statement:
>
> sfTextEntryBase::~sfTextEntryBase (D.2245_8);
>
> is still connected to the original region 5.  So remove_unreachable_handlers
> computes that region 12 is unreachable and turns resx 12 into a trap, which
> is caught by an assertion because the successor L10 isn't reachable any more.
>
> Partial inlining already punts on external RESXs:
>
>      /* FIXME: We can split regions containing EH.  We can not however
>         split RESX, EH_DISPATCH and EH_POINTER referring to same region
>         into different partitions.  This would require tracking of
>         EH regions and checking in consider_split_point if they
>         are not used elsewhere.  */
>      if (gimple_code (stmt) == GIMPLE_RESX
>          && stmt_can_throw_external (stmt))
>        {
>          if (dump_file && (dump_flags & TDF_DETAILS))
>            fprintf (dump_file, "Cannot split: external resx.\n");
>          can_split = false;
>        }
>
> but it seems to me that the "external" is bogus here, hence the proposed fix.
>
> Tested on i586-suse-linux, OK for the mainline?

Ok.

Thanks,
Richard.

>
> 2011-02-11  Eric Botcazou  <ebotcazou@adacore.com>
>
>        PR tree-optimization/47420
>        * ipa-split.c (visit_bb): Put on any kind of GIMPLE_RESX.
>
>
> 2011-02-11  Eric Botcazou  <ebotcazou@adacore.com>
>
>        * g++.dg/opt/inline17.C: New test.
>
>
> --
> Eric Botcazou
>

Patch

Index: ipa-split.c
===================================================================
--- ipa-split.c	(revision 169914)
+++ ipa-split.c	(working copy)
@@ -643,11 +643,10 @@  visit_bb (basic_block bb, basic_block re
 	 into different partitions.  This would require tracking of
 	 EH regions and checking in consider_split_point if they 
 	 are not used elsewhere.  */
-      if (gimple_code (stmt) == GIMPLE_RESX
-	  && stmt_can_throw_external (stmt))
+      if (gimple_code (stmt) == GIMPLE_RESX)
 	{
 	  if (dump_file && (dump_flags & TDF_DETAILS))
-	    fprintf (dump_file, "Cannot split: external resx.\n");
+	    fprintf (dump_file, "Cannot split: resx.\n");
 	  can_split = false;
 	}
       if (gimple_code (stmt) == GIMPLE_EH_DISPATCH)