gcc: Revert 357c435 and 49a714e
This commit reverts https://github.com/gcc-mirror/gcc/commit/357c435 and https://github.com/gcc-mirror/gcc/commit/49a714e Reference: https://github.com/msys2/MINGW-packages/issues/8094
This commit is contained in:
committed by
Christoph Reiter
parent
2d13e21759
commit
a43f3fadaa
225
mingw-w64-gcc/0201-backport-49a714e.patch
Normal file
225
mingw-w64-gcc/0201-backport-49a714e.patch
Normal file
@@ -0,0 +1,225 @@
|
||||
From 49a714e59194a7c549aa6657676a1b4be4520650 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Botcazou <ebotcazou@adacore.com>
|
||||
Date: Mon, 1 Mar 2021 07:53:05 +0100
|
||||
Subject: [PATCH] Fix wrong result for 1.0/3.0 at -O2 -fno-omit-frame-pointer
|
||||
-frounding-math
|
||||
|
||||
This wrong-code PR for the C++ compiler on x86-64/Windows is a regression
|
||||
in GCC 9 and later, but the underlying issue has probably been there since
|
||||
SEH was implemented and is exposed by this comment in config/i386/winnt.c:
|
||||
|
||||
/* SEH records saves relative to the "current" stack pointer, whether
|
||||
or not there's a frame pointer in place. This tracks the current
|
||||
stack pointer offset from the CFA. */
|
||||
HOST_WIDE_INT sp_offset;
|
||||
|
||||
That's not what the (current) Microsoft documentation says; instead it says:
|
||||
|
||||
/* SEH records offsets relative to the lowest address of the fixed stack
|
||||
allocation. If there is no frame pointer, these offsets are from the
|
||||
stack pointer; if there is a frame pointer, these offsets are from the
|
||||
value of the stack pointer when the frame pointer was established, i.e.
|
||||
the frame pointer minus the offset in the .seh_setframe directive. */
|
||||
|
||||
That's why the implementation is correct only under the condition that the
|
||||
frame pointer be established *after* the fixed stack allocation; as a matter
|
||||
of fact, that's clearly the model underpinning SEH, but is the opposite of
|
||||
what is done e.g. on Linux.
|
||||
|
||||
However the issue is mostly papered over in practice because:
|
||||
|
||||
1. SEH forces use_fast_prologue_epilogue to false, which in turns forces
|
||||
save_regs_using_mov to false, so the general regs are always pushed when
|
||||
they need to be saved, which eliminates the offset computation for them.
|
||||
|
||||
2. As soon as a frame is larger than 240 bytes, the frame pointer is fixed
|
||||
arbitrarily to 128 bytes above the stack pointer, which of course requires
|
||||
that it be established after the fixed stack allocation.
|
||||
|
||||
So you need a small frame clobbering one of the call-saved XMM registers in
|
||||
order to generate wrong SEH unwind info.
|
||||
|
||||
The attached fix makes sure that the frame pointer is always established
|
||||
after the fixed stack allocation by pointing it at or below the lowest used
|
||||
register save area, i.e. the SSE save area, and removing the special early
|
||||
saves in the prologue; the end result is a uniform prologue sequence for
|
||||
SEH whatever the frame size. And it avoids a discrepancy between cases
|
||||
where the number of saved general regs is even and cases where it is odd.
|
||||
|
||||
gcc/
|
||||
PR target/99234
|
||||
* config/i386/i386.c (ix86_compute_frame_layout): For a SEH target,
|
||||
point the hard frame pointer to the SSE register save area instead
|
||||
of the general register save area. Perform only minimal adjustment
|
||||
for small frames if it is initially not correctly aligned.
|
||||
(ix86_expand_prologue): Remove early saves for a SEH target.
|
||||
* config/i386/winnt.c (struct seh_frame_state): Document constraint.
|
||||
gcc/testsuite/
|
||||
* g++.dg/eh/seh-xmm-unwind.C: New test.
|
||||
---
|
||||
gcc/config/i386/i386.c | 35 +++++---------
|
||||
gcc/config/i386/winnt.c | 17 +++++--
|
||||
gcc/testsuite/g++.dg/eh/seh-xmm-unwind.C | 61 ++++++++++++++++++++++++
|
||||
3 files changed, 88 insertions(+), 25 deletions(-)
|
||||
create mode 100644 gcc/testsuite/g++.dg/eh/seh-xmm-unwind.C
|
||||
|
||||
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
|
||||
index aedf7873ce5..7b803661366 100644
|
||||
--- a/gcc/config/i386/i386.c
|
||||
+++ b/gcc/config/i386/i386.c
|
||||
@@ -6190,11 +6190,6 @@ ix86_compute_frame_layout (void)
|
||||
offset += frame->nregs * UNITS_PER_WORD;
|
||||
frame->reg_save_offset = offset;
|
||||
|
||||
- /* On SEH target, registers are pushed just before the frame pointer
|
||||
- location. */
|
||||
- if (TARGET_SEH)
|
||||
- frame->hard_frame_pointer_offset = offset;
|
||||
-
|
||||
/* Calculate the size of the va-arg area (not including padding, if any). */
|
||||
frame->va_arg_size = ix86_varargs_gpr_size + ix86_varargs_fpr_size;
|
||||
|
||||
@@ -6357,14 +6352,21 @@ ix86_compute_frame_layout (void)
|
||||
the unwind data structure. */
|
||||
if (TARGET_SEH)
|
||||
{
|
||||
- HOST_WIDE_INT diff;
|
||||
+ /* Force the frame pointer to point at or below the lowest register save
|
||||
+ area, see the SEH code in config/i386/winnt.c for the rationale. */
|
||||
+ frame->hard_frame_pointer_offset = frame->sse_reg_save_offset;
|
||||
|
||||
- /* If we can leave the frame pointer where it is, do so. Also, returns
|
||||
+ /* If we can leave the frame pointer where it is, do so. Also, return
|
||||
the establisher frame for __builtin_frame_address (0). */
|
||||
- diff = frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
|
||||
- if (diff <= SEH_MAX_FRAME_SIZE
|
||||
- && (diff > 240 || (diff & 15) != 0)
|
||||
- && !crtl->accesses_prior_frames)
|
||||
+ const HOST_WIDE_INT diff
|
||||
+ = frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
|
||||
+ if (diff <= 255)
|
||||
+ {
|
||||
+ /* The resulting diff will be a multiple of 16 lower than 255,
|
||||
+ i.e. at most 240 as required by the unwind data structure. */
|
||||
+ frame->hard_frame_pointer_offset += (diff & 15);
|
||||
+ }
|
||||
+ else if (diff <= SEH_MAX_FRAME_SIZE && !crtl->accesses_prior_frames)
|
||||
{
|
||||
/* Ideally we'd determine what portion of the local stack frame
|
||||
(within the constraint of the lowest 240) is most heavily used.
|
||||
@@ -8170,17 +8172,6 @@ ix86_expand_prologue (void)
|
||||
insn = emit_insn (gen_push (hard_frame_pointer_rtx));
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
- /* Push registers now, before setting the frame pointer
|
||||
- on SEH target. */
|
||||
- if (!int_registers_saved
|
||||
- && TARGET_SEH
|
||||
- && !frame.save_regs_using_mov)
|
||||
- {
|
||||
- ix86_emit_save_regs ();
|
||||
- int_registers_saved = true;
|
||||
- gcc_assert (m->fs.sp_offset == frame.reg_save_offset);
|
||||
- }
|
||||
-
|
||||
if (m->fs.sp_offset == frame.hard_frame_pointer_offset)
|
||||
{
|
||||
insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
|
||||
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
|
||||
index eae3ee2ef9a..201f69e74c4 100644
|
||||
--- a/gcc/config/i386/winnt.c
|
||||
+++ b/gcc/config/i386/winnt.c
|
||||
@@ -830,9 +830,20 @@ i386_pe_asm_lto_end (void)
|
||||
|
||||
struct seh_frame_state
|
||||
{
|
||||
- /* SEH records saves relative to the "current" stack pointer, whether
|
||||
- or not there's a frame pointer in place. This tracks the current
|
||||
- stack pointer offset from the CFA. */
|
||||
+ /* SEH records offsets relative to the lowest address of the fixed stack
|
||||
+ allocation. If there is no frame pointer, these offsets are from the
|
||||
+ stack pointer; if there is a frame pointer, these offsets are from the
|
||||
+ value of the stack pointer when the frame pointer was established, i.e.
|
||||
+ the frame pointer minus the offset in the .seh_setframe directive.
|
||||
+
|
||||
+ We do not distinguish these two cases, i.e. we consider that the offsets
|
||||
+ are always relative to the "current" stack pointer. This means that we
|
||||
+ need to perform the fixed stack allocation before establishing the frame
|
||||
+ pointer whenever there are registers to be saved, and this is guaranteed
|
||||
+ by the prologue provided that we force the frame pointer to point at or
|
||||
+ below the lowest used register save area, see ix86_compute_frame_layout.
|
||||
+
|
||||
+ This tracks the current stack pointer offset from the CFA. */
|
||||
HOST_WIDE_INT sp_offset;
|
||||
|
||||
/* The CFA is located at CFA_REG + CFA_OFFSET. */
|
||||
diff --git a/gcc/testsuite/g++.dg/eh/seh-xmm-unwind.C b/gcc/testsuite/g++.dg/eh/seh-xmm-unwind.C
|
||||
new file mode 100644
|
||||
index 00000000000..07fd805b3fd
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/g++.dg/eh/seh-xmm-unwind.C
|
||||
@@ -0,0 +1,61 @@
|
||||
+/* PR target/99234 */
|
||||
+/* Test SEH unwinding of XMM register saves. */
|
||||
+
|
||||
+/* { dg-do run { target { x86_64-*-mingw32 && lp64 } } } */
|
||||
+
|
||||
+extern "C" void abort (void);
|
||||
+extern "C" void exit (int);
|
||||
+
|
||||
+void
|
||||
+foo (void)
|
||||
+{
|
||||
+ register __int128 xmm6 asm("xmm6") = 0;
|
||||
+ register __int128 xmm7 asm("xmm7") = 0;
|
||||
+ register __int128 xmm8 asm("xmm8") = 0;
|
||||
+ register __int128 xmm9 asm("xmm9") = 0;
|
||||
+ register __int128 xmm10 asm("xmm10") = 0;
|
||||
+ register __int128 xmm11 asm("xmm11") = 0;
|
||||
+ register __int128 xmm12 asm("xmm12") = 0;
|
||||
+ register __int128 xmm13 asm("xmm13") = 0;
|
||||
+ register __int128 xmm14 asm("xmm14") = 0;
|
||||
+ register __int128 xmm15 asm("xmm15") = 0;
|
||||
+
|
||||
+ __asm__ __volatile__ ("" : "+x" (xmm6), "+x" (xmm7), "+x" (xmm8), "+x" (xmm9),
|
||||
+ "+x" (xmm10), "+x" (xmm11), "+x" (xmm12), "+x" (xmm13),
|
||||
+ "+x" (xmm14), "+x" (xmm15));
|
||||
+
|
||||
+ throw 1;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+ register __int128 xmm6 asm("xmm6") = 6;
|
||||
+ register __int128 xmm7 asm("xmm7") = 7;
|
||||
+ register __int128 xmm8 asm("xmm8") = 8;
|
||||
+ register __int128 xmm9 asm("xmm9") = 9;
|
||||
+ register __int128 xmm10 asm("xmm10") = 10;
|
||||
+ register __int128 xmm11 asm("xmm11") = 11;
|
||||
+ register __int128 xmm12 asm("xmm12") = 12;
|
||||
+ register __int128 xmm13 asm("xmm13") = 13;
|
||||
+ register __int128 xmm14 asm("xmm14") = 14;
|
||||
+ register __int128 xmm15 asm("xmm15") = 15;
|
||||
+
|
||||
+ __asm__ __volatile__ ("" : "+x" (xmm6), "+x" (xmm7), "+x" (xmm8), "+x" (xmm9),
|
||||
+ "+x" (xmm10), "+x" (xmm11), "+x" (xmm12), "+x" (xmm13),
|
||||
+ "+x" (xmm14), "+x" (xmm15));
|
||||
+
|
||||
+ try {
|
||||
+ foo ();
|
||||
+ } catch (...) {
|
||||
+ __asm__ __volatile__ ("" : "+x" (xmm6), "+x" (xmm7), "+x" (xmm8), "+x" (xmm9),
|
||||
+ "+x" (xmm10), "+x" (xmm11), "+x" (xmm12), "+x" (xmm13),
|
||||
+ "+x" (xmm14), "+x" (xmm15));
|
||||
+
|
||||
+ if (xmm6 != 6 || xmm7 != 7 || xmm8 != 8 || xmm9 != 9 || xmm10 != 10
|
||||
+ || xmm11 != 11 || xmm12 != 12 || xmm13 != 13 || xmm14 != 14 || xmm15 != 15)
|
||||
+ abort ();
|
||||
+ }
|
||||
+
|
||||
+ exit (0);
|
||||
+}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
40
mingw-w64-gcc/0202-backport-2939b35.patch
Normal file
40
mingw-w64-gcc/0202-backport-2939b35.patch
Normal file
@@ -0,0 +1,40 @@
|
||||
From 2939b358936bb824330888def98ad848dea41483 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Botcazou <ebotcazou@adacore.com>
|
||||
Date: Wed, 3 Mar 2021 12:25:03 +0100
|
||||
Subject: [PATCH] Fix ICE with pathologically large frames
|
||||
|
||||
gcc/
|
||||
PR target/99234
|
||||
* config/i386/i386.c (ix86_compute_frame_layout): For a SEH target,
|
||||
point back the hard frame pointer to its default location when the
|
||||
frame is larger than SEH_MAX_FRAME_SIZE.
|
||||
---
|
||||
gcc/config/i386/i386.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
|
||||
index 7b803661366..e23f92b58cc 100644
|
||||
--- a/gcc/config/i386/i386.c
|
||||
+++ b/gcc/config/i386/i386.c
|
||||
@@ -6357,7 +6357,8 @@ ix86_compute_frame_layout (void)
|
||||
frame->hard_frame_pointer_offset = frame->sse_reg_save_offset;
|
||||
|
||||
/* If we can leave the frame pointer where it is, do so. Also, return
|
||||
- the establisher frame for __builtin_frame_address (0). */
|
||||
+ the establisher frame for __builtin_frame_address (0) or else if the
|
||||
+ frame overflows the SEH maximum frame size. */
|
||||
const HOST_WIDE_INT diff
|
||||
= frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
|
||||
if (diff <= 255)
|
||||
@@ -6375,6 +6376,8 @@ ix86_compute_frame_layout (void)
|
||||
frame that is addressable with 8-bit offsets. */
|
||||
frame->hard_frame_pointer_offset = frame->stack_pointer_offset - 128;
|
||||
}
|
||||
+ else
|
||||
+ frame->hard_frame_pointer_offset = frame->hfp_save_offset;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@@ -75,7 +75,9 @@ source=("https://ftp.gnu.org/gnu/gcc/${_realname}-${pkgver%%+*}/${_realname}-${p
|
||||
0140-gcc-8.2.0-diagnostic-color.patch
|
||||
0150-gcc-10.2.0-libgcc-ldflags.patch
|
||||
0160-libbacktrace-seh.patch
|
||||
0200-ms_printf-improvements.patch)
|
||||
0200-ms_printf-improvements.patch
|
||||
0201-backport-49a714e.patch
|
||||
0202-backport-2939b35.patch)
|
||||
sha256sums=('64f404c1a650f27fc33da242e1f2df54952e3963a49e06e73f6940f3223ac344'
|
||||
'SKIP'
|
||||
'bce81824fc89e5e62cca350de4c17a27e27a18a1a1ad5ca3492aec1fc5af3234'
|
||||
@@ -99,7 +101,9 @@ sha256sums=('64f404c1a650f27fc33da242e1f2df54952e3963a49e06e73f6940f3223ac344'
|
||||
'5240a9e731b45c17a164066c7eb193c1fbee9fd8d9a2a5afa2edbcde9510da47'
|
||||
'7f0b4e45d933e18c9d8bd2afcd83e4f52e97e2e25dd41bfa0cba755c70e591c7'
|
||||
'88c1d65e763e631ad49f9a077ed631f4acac9ef4732e2818ccddaefc883b1811'
|
||||
'146ac7aec004a949e42f7da6ff66351790e56094a85f6dbe28ea583b47c8125d')
|
||||
'146ac7aec004a949e42f7da6ff66351790e56094a85f6dbe28ea583b47c8125d'
|
||||
'6bcaf2846ceeafa87912b30ed3e573d75b35bbeafebdaf675e2318b9b0058fbb'
|
||||
'319b1ffe9dbede0578ffa4fd78fe803bf40ed1e0bc52251fdaaadd869f0dbf2a')
|
||||
validpgpkeys=(F3691687D867B81B51CE07D9BBE43771487328A9 # bpiotrowski@archlinux.org
|
||||
86CFFCA918CF3AF47147588051E8B148A9999C34 # evangelos@foutrelis.com
|
||||
13975A70E63C361C73AE69EF6EEB81F8981C74C7 # richard.guenther@gmail.com
|
||||
@@ -168,6 +172,16 @@ prepare() {
|
||||
apply_patch_with_msg \
|
||||
0200-ms_printf-improvements.patch
|
||||
|
||||
# Fix ICE with pathologically large frames, a fix for 0201
|
||||
# Does not fix the crash for Webots introduced by 0201 below
|
||||
# https://github.com/gcc-mirror/gcc/commit/357c435
|
||||
patch -R -p1 -i "${srcdir}/0202-backport-2939b35.patch"
|
||||
|
||||
# Apparently it had some adverse impacts on setjmp and crash Webots at start-up
|
||||
# https://github.com/msys2/MINGW-packages/issues/8094
|
||||
# https://github.com/gcc-mirror/gcc/commit/49a714e
|
||||
patch -R -p1 -i "${srcdir}/0201-backport-49a714e.patch"
|
||||
|
||||
# do not expect ${prefix}/mingw symlink - this should be superceded by
|
||||
# 0005-Windows-Don-t-ignore-native-system-header-dir.patch .. but isn't!
|
||||
sed -i 's/${prefix}\/mingw\//${prefix}\//g' configure
|
||||
|
||||
Reference in New Issue
Block a user