public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [x86] Fix another -freorder-blocks-and-partition glitch with Windows SEH
@ 2021-04-19  8:27 Eric Botcazou
  0 siblings, 0 replies; only message in thread
From: Eric Botcazou @ 2021-04-19  8:27 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1006 bytes --]

Since GCC 8, the -freorder-blocks-and-partition pass can split a function into 
hot and cold parts, thus generating 2 FDEs for a single function in DWARF for 
exception purposes and doing an equivalent trick for Windows SEH on x86-64.

Now the Windows system unwinder does not support arbitrarily large frames and 
there is even a hard limit on the encoding of the CFI, which changes the stack 
allocation strategy when it is topped and which must be reflected everywhere.

I overlooked that when implementing the -freorder-blocks-and-partition support 
back in 2018 and this results in an ICE when gigantic frames, like e.g. in the 
attached Ada testcase.

Bootstrapped on x86-64/Windows, applied on all active branches as obvious.


2021-04-19  Eric Botcazou  <ebotcazou@adacore.com>

	* config/i386/winnt.c (i386_pe_seh_cold_init): Properly deal with
	frames larger than the SEH maximum frame size.


2021-04-19  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/opt92.adb: New test.

-- 
Eric Botcazou

[-- Attachment #2: p.diff --]
[-- Type: text/x-patch, Size: 1638 bytes --]

diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index cc121965294..b66263ad243 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -921,15 +921,17 @@ i386_pe_seh_cold_init (FILE *f, const char *name)
 
   /* In the normal case, the frame pointer is near the bottom of the frame
      so we can do the full stack allocation and set it afterwards.  There
-     is an exception when the function accesses prior frames so, in this
-     case, we need to pre-allocate a small chunk before setting it.  */
-  if (crtl->accesses_prior_frames)
-    alloc_offset = seh->cfa_offset;
-  else
+     is an exception if the function overflows the SEH maximum frame size
+     or accesses prior frames so, in this case, we need to pre-allocate a
+     small chunk of stack before setting it.  */
+  offset = seh->sp_offset - INCOMING_FRAME_SP_OFFSET;
+  if (offset < SEH_MAX_FRAME_SIZE && !crtl->accesses_prior_frames)
     alloc_offset = seh->sp_offset;
+  else
+    alloc_offset = MIN (seh->cfa_offset + 240, seh->sp_offset);
 
   offset = alloc_offset - INCOMING_FRAME_SP_OFFSET;
-  if (offset > 0 && offset < SEH_MAX_FRAME_SIZE)
+  if (offset > 0)
     fprintf (f, "\t.seh_stackalloc\t" HOST_WIDE_INT_PRINT_DEC "\n", offset);
 
   for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
@@ -958,7 +960,7 @@ i386_pe_seh_cold_init (FILE *f, const char *name)
       fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC "\n", offset);
     }
 
-  if (crtl->accesses_prior_frames)
+  if (alloc_offset != seh->sp_offset)
     {
       offset = seh->sp_offset - alloc_offset;
       if (offset > 0 && offset < SEH_MAX_FRAME_SIZE)

[-- Attachment #3: opt92.adb --]
[-- Type: text/x-adasrc, Size: 865 bytes --]

-- { dg-do compile { target { lp64 || llp64 } } }
-- { dg-options "-O2 -gnatws" }

procedure Main is

   subtype Int64 is Long_Long_Integer;

   type Arr is array (Int64 range <>) of Boolean;

   Pow : constant := 10;

   procedure Compute (B : in out Arr) is
      Factor : Int64 := 3;
      Num    : Int64;
   begin
      while Factor <= 10 ** (Pow / 2) loop
         Num := Factor;
         while Num < 10 ** Pow loop
            if B (Num) then
               Factor := Num;
               exit;
            end if;
            Num := Num + 2;
         end loop;
         Num := Factor * Factor;
         while Num < 10 ** Pow loop
            B (Num) := False;
            Num        := Num + Factor * 2;
         end loop;
         Factor := Factor + 2;
      end loop;
   end;

   B : Arr (1 .. 10 ** Pow) := (others => True);

begin
   Compute (B);   
end;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-04-19  8:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-19  8:27 [x86] Fix another -freorder-blocks-and-partition glitch with Windows SEH Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).