Bug 79793 - Incorrect stack alignment for interrupt handler in 64-bit
Summary: Incorrect stack alignment for interrupt handler in 64-bit
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: 7.2
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on: 81570
Blocks:
  Show dependency treegraph
 
Reported: 2017-03-01 21:28 UTC by H.J. Lu
Modified: 2017-09-13 16:05 UTC (History)
0 users

See Also:
Host:
Target: x86-64
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-03-13 00:00:00


Attachments
Adjust INCOMING_FRAME_SP_OFFSET for TYPE_EXCEPTION functions (890 bytes, patch)
2017-07-25 11:01 UTC, Uroš Bizjak
Details | Diff
An untested patch (1.91 KB, patch)
2017-07-25 11:45 UTC, H.J. Lu
Details | Diff
An updated patch (2.10 KB, patch)
2017-07-25 12:03 UTC, H.J. Lu
Details | Diff
An untested patch (2.24 KB, patch)
2017-07-25 12:29 UTC, H.J. Lu
Details | Diff
An untested patch (2.37 KB, patch)
2017-07-26 11:50 UTC, H.J. Lu
Details | Diff
A patch (2.10 KB, patch)
2017-07-26 22:05 UTC, H.J. Lu
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2017-03-01 21:28:16 UTC
Section I6.14.2 64-Bit Mode Stack Frame in Intel SDM Vol 3 has

In IA-32e mode, the RSP is aligned to a 16-byte boundary before pushing the stack
frame. The stack frame itself is aligned on a 16-byte boundary when the interrupt
handler is called.

static unsigned int
ix86_minimum_incoming_stack_boundary (bool sibcall)
{
  unsigned int incoming_stack_boundary;

  /* Stack of interrupt handler is always aligned to MIN_STACK_BOUNDARY.
   */
  if (cfun->machine->func_type != TYPE_NORMAL)
    incoming_stack_boundary = MIN_STACK_BOUNDARY;

is incorrect for 64-bit mode.
Comment 1 Richard Biener 2017-03-02 08:58:42 UTC
Well, not "incorrect" but too conservative.
Comment 2 Julia Koval 2017-03-03 15:21:01 UTC
Patch posted at
https://gcc.gnu.org/ml/gcc-patches/2017-03/msg00178.html
Comment 3 hjl@gcc.gnu.org 2017-03-06 16:09:31 UTC
Author: hjl
Date: Mon Mar  6 16:08:59 2017
New Revision: 245926

URL: https://gcc.gnu.org/viewcvs?rev=245926&root=gcc&view=rev
Log:
Set incoming stack boundary to 128 for 64-bit targets

For 64-bit targets, the incoming stack of interrupt handler is aligned
to 16 bytes.  Update ix86_minimum_incoming_stack_boundary to set the
incoming stack boundary of interrupt handler to 128 for 64-bit targets.

gcc/

2017-03-06  Julia Koval  <julia.koval@intel.com>

	PR target/79793
	* config/i386/i386.c (ix86_minimum_incoming_stack_boundary): Set
	incoming stack boundary to 128 for 64-bit targets.

gcc/testsuite/

2017-03-06  Julia Koval  <julia.koval@intel.com>

	PR target/79793
	 * gcc.target/i386/interrupt-12.c: Update scan-assembler-times
	 directives.
	 * gcc.target/i386/interrupt-13.c: Ditto.
	 * gcc.target/i386/interrupt-14.c: Ditto.
	 * gcc.target/i386/interrupt-15.c: Ditto.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.target/i386/interrupt-12.c
    trunk/gcc/testsuite/gcc.target/i386/interrupt-13.c
    trunk/gcc/testsuite/gcc.target/i386/interrupt-14.c
    trunk/gcc/testsuite/gcc.target/i386/interrupt-15.c
Comment 4 H.J. Lu 2017-03-06 16:10:08 UTC
Fixed for GCC 7.
Comment 5 H.J. Lu 2017-03-13 20:12:30 UTC
In 64-bit mode, stack is 16-byte aligned when entering handler.  But if
there is error code

SS
RSP
FLAGS
CS
RIP
Error Code

the stack alignment is off by 8 bytes.  That is %rsp + 8 isn't multiple
of 16 at the start of handler.
Comment 6 Jakub Jelinek 2017-05-02 15:55:48 UTC
GCC 7.1 has been released.
Comment 7 H.J. Lu 2017-07-24 23:20:11 UTC
(In reply to H.J. Lu from comment #5)
> In 64-bit mode, stack is 16-byte aligned when entering handler.  But if
> there is error code
> 
> SS
> RSP
> FLAGS
> CS
> RIP
> Error Code
> 
> the stack alignment is off by 8 bytes.  That is %rsp + 8 isn't multiple
> of 16 at the start of handler.

A testcase:

[hjl@gnu-skl-1 pr79793]$ cat y.c
#include <fxsrintrin.h>

typedef unsigned int uword_t __attribute__ ((mode (__word__)));

struct interrupt_frame
{
  uword_t ip;
  uword_t cs;
  uword_t flags;
  uword_t sp;
  uword_t ss;
};

__attribute__((interrupt))
void
fn (struct interrupt_frame *frame, uword_t error)
{
  char fxsave_region [512] __attribute__((aligned(16)));
  _fxsave64 (fxsave_region);
}
[hjl@gnu-skl-1 pr79793]$ make y.s
/export/build/gnu/gcc-x32-7/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc-x32-7/build-x86_64-linux/gcc/ -O2 -mgeneral-regs-only -S -o y.s y.c
[hjl@gnu-skl-1 pr79793]$ cat y.s
	.file	"y.c"
	.text
	.p2align 4,,15
	.globl	fn
	.type	fn, @function
fn:
.LFB4:
	.cfi_startproc
	subq	$400, %rsp
	.cfi_def_cfa_offset 408
	fxsave64	-120(%rsp)
	addq	$408, %rsp
	iretq
	.cfi_endproc
.LFE4:
	.size	fn, .-fn
	.ident	"GCC: (GNU) 7.1.1 20170724"
	.section	.note.GNU-stack,"",@progbits
[hjl@gnu-skl-1 pr79793]$ 

-120(%rsp) isn't aligned at 16 bytes.

For

[hjl@gnu-skl-1 pr79793]$ cat x.c
#include <fxsrintrin.h>

typedef unsigned int uword_t __attribute__ ((mode (__word__)));

struct interrupt_frame
{
  uword_t ip;
  uword_t cs;
  uword_t flags;
  uword_t sp;
  uword_t ss;
};

__attribute__((interrupt))
void
fn (struct interrupt_frame *frame)
{
  char fxsave_region [512] __attribute__((aligned(16)));
  _fxsave64 (fxsave_region);
}
[hjl@gnu-skl-1 pr79793]$ make x.s
/export/build/gnu/gcc-x32-7/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc-x32-7/build-x86_64-linux/gcc/ -O2 -mgeneral-regs-only -S -o x.s x.c
[hjl@gnu-skl-1 pr79793]$ cat x.s
	.file	"x.c"
	.text
	.p2align 4,,15
	.globl	fn
	.type	fn, @function
fn:
.LFB4:
	.cfi_startproc
	subq	$400, %rsp
	.cfi_def_cfa_offset 408
	fxsave64	-120(%rsp)
	addq	$400, %rsp
	.cfi_def_cfa_offset 8
	iretq
	.cfi_endproc
.LFE4:
	.size	fn, .-fn
	.ident	"GCC: (GNU) 7.1.1 20170724"
	.section	.note.GNU-stack,"",@progbits
[hjl@gnu-skl-1 pr79793]$ 

-120(%rsp) is aligned at 16 bytes.
Comment 8 H.J. Lu 2017-07-24 23:29:19 UTC
clang 5.0 handles stack alignment correctly:

[hjl@gnu-skl-1 pr79793]$ cat x.c
typedef unsigned int uword_t __attribute__ ((mode (__word__)));

__attribute__((interrupt))
void
fn (void *frame)
{
  char fxsave_region [512] __attribute__((aligned(16)));
  __builtin_ia32_fxsave (fxsave_region);
}
[hjl@gnu-skl-1 pr79793]$ cat y.c
typedef unsigned int uword_t __attribute__ ((mode (__word__)));

__attribute__((interrupt))
void
fn (void *frame, uword_t error)
{
  char fxsave_region [512] __attribute__((aligned(16)));
  __builtin_ia32_fxsave (fxsave_region);
}
[hjl@gnu-skl-1 pr79793]$ make 
/export/build/gnu/llvm-clang/build-x86_64-linux/bin/clang -O2 -mgeneral-regs-only -S -o y.s y.c
clang-5.0: warning: argument unused during compilation: '-mgeneral-regs-only' [-Wunused-command-line-argument]
[hjl@gnu-skl-1 pr79793]$ cat x.s
	.text
	.file	"x.c"
	.globl	fn                      # -- Begin function fn
	.p2align	4, 0x90
	.type	fn,@function
fn:                                     # @fn
	.cfi_startproc
# BB#0:                                 # %entry
	subq	$392, %rsp              # imm = 0x188
.Lcfi0:
	.cfi_def_cfa_offset 400
	cld
	fxsave	-128(%rsp)
	addq	$392, %rsp              # imm = 0x188
	iretq
.Lfunc_end0:
	.size	fn, .Lfunc_end0-fn
	.cfi_endproc
                                        # -- End function

	.ident	"clang version 5.0.0 (http://llvm.org/git/clang.git f53edbb006df3bc205bf38008d96de510b2adddd) (http://llvm.org/git/llvm.git 9889fe2290766430b99a2d4fadbc5ba92f8004b6)"
	.section	".note.GNU-stack","",@progbits
[hjl@gnu-skl-1 pr79793]$ cat y.s
	.text
	.file	"y.c"
	.globl	fn                      # -- Begin function fn
	.p2align	4, 0x90
	.type	fn,@function
fn:                                     # @fn
	.cfi_startproc
# BB#0:                                 # %entry
	pushq	%rax
	subq	$400, %rsp              # imm = 0x190
.Lcfi0:
	.cfi_def_cfa_offset 408
	cld
	fxsave	-120(%rsp)
	addq	$400, %rsp              # imm = 0x190
	addq	$16, %rsp
	iretq
.Lfunc_end0:
	.size	fn, .Lfunc_end0-fn
	.cfi_endproc
                                        # -- End function

	.ident	"clang version 5.0.0 (http://llvm.org/git/clang.git f53edbb006df3bc205bf38008d96de510b2adddd) (http://llvm.org/git/llvm.git 9889fe2290766430b99a2d4fadbc5ba92f8004b6)"
	.section	".note.GNU-stack","",@progbits
[hjl@gnu-skl-1 pr79793]$
Comment 9 Uroš Bizjak 2017-07-25 11:01:40 UTC
Created attachment 41826 [details]
Adjust INCOMING_FRAME_SP_OFFSET for TYPE_EXCEPTION functions

How about something like attached patch? The patch adjusts INCOMING_FRAME_SP_OFFSET of an exception handler to 2 * UNITS_PER_WORD.

The resulting code reads:

        .cfi_startproc
        subq    $392, %rsp
        .cfi_def_cfa_offset 400
        fxsave64        -120(%rsp)
        addq    $400, %rsp
        .cfi_def_cfa_offset 0
        iretq
        .cfi_endproc

Patch is otherwise untested. Probably, function argument parsing code has to be adjusted as well. I'm also not sure if all .cfi directives are correct.
Comment 10 H.J. Lu 2017-07-25 11:45:44 UTC
Created attachment 41827 [details]
An untested patch
Comment 11 H.J. Lu 2017-07-25 11:49:50 UTC
(In reply to Uroš Bizjak from comment #9)
> Created attachment 41826 [details]
> Adjust INCOMING_FRAME_SP_OFFSET for TYPE_EXCEPTION functions
> 
> How about something like attached patch? The patch adjusts
> INCOMING_FRAME_SP_OFFSET of an exception handler to 2 * UNITS_PER_WORD.
> 
> The resulting code reads:
> 
>         .cfi_startproc
>         subq    $392, %rsp
>         .cfi_def_cfa_offset 400
>         fxsave64        -120(%rsp)
>         addq    $400, %rsp
>         .cfi_def_cfa_offset 0
>         iretq
>         .cfi_endproc
> 
> Patch is otherwise untested. Probably, function argument parsing code has to
> be adjusted as well. I'm also not sure if all .cfi directives are correct.

Our patches are very similar.  Mine passed most of interrupt tests.
Comment 12 H.J. Lu 2017-07-25 12:03:11 UTC
Created attachment 41828 [details]
An updated patch

Update gcc.dg/guality/pr68037-1.c.  I got

FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 error == 0x12345670
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->ip == 0x12345671
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->cs == 0x12345672
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->flags == 0x12345673
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->sp == 0x12345674
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->ss == 0x12345675

and

Running target unix/-m32
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using /export/gnu/import/git/sources/gcc/gcc/testsuite/config/default.exp as tool-and-target-specific interface file.
Running /export/gnu/import/git/sources/gcc/gcc/testsuite/gcc.target/i386/i386.exp ...
FAIL: gcc.target/i386/interrupt-12.c scan-assembler-times movl[\\t ]*-4\\(%ebp\\),[\\t ]*%eax 1
FAIL: gcc.target/i386/interrupt-13.c scan-assembler-times movl[\\t ]*-4\\(%ebp\\),[\\t ]*%eax 1
FAIL: gcc.target/i386/interrupt-15.c scan-assembler-times movl[\\t ]*-4\\(%ebp\\),[\\t ]*%eax 2

		=== gcc Summary for unix/-m32 ===

# of expected passes		211
# of unexpected failures	3
# of unsupported tests		2
Comment 13 H.J. Lu 2017-07-25 12:29:33 UTC
Created attachment 41830 [details]
An untested patch

The only interrupt failures are

FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 error == 0x12345670
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->ip == 0x12345671
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->cs == 0x12345672
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->flags == 0x12345673
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->sp == 0x12345674
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->ss == 0x12345675
Comment 14 H.J. Lu 2017-07-26 11:50:41 UTC
Created attachment 41834 [details]
An untested patch
Comment 15 H.J. Lu 2017-07-26 22:05:39 UTC
Created attachment 41839 [details]
A patch

-g -O2 -flto generates:

Dump of assembler code for function fn:
   0x0000000000400550 <+0>:	push   %rdi
   0x0000000000400551 <+1>:	sub    $0x8,%rsp
   0x0000000000400555 <+5>:	cmpq   $0x12345670,0x10(%rsp)
   0x000000000040055e <+14>:	jne    0x400430 <fn>
=> 0x0000000000400564 <+20>:	cmpq   $0x12345671,0x18(%rsp)

with debug info:

00000084 0000000000000018 00000058 FDE cie=00000030 pc=0000000000400550..00000000004005b7
  DW_CFA_advance_loc: 1 to 0000000000400551
  DW_CFA_def_cfa_offset: 16
  DW_CFA_offset: r5 (rdi) at cfa-16
  DW_CFA_advance_loc: 4 to 0000000000400555
  DW_CFA_def_cfa_offset: 24
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

-g -O2 generates:

   0x0000000000400550 <+0>:	push   %rdi
   0x0000000000400551 <+1>:	sub    $0x8,%rsp
   0x0000000000400555 <+5>:	cmpq   $0x12345670,0x10(%rsp)
   0x000000000040055e <+14>:	jne    0x400430 <fn>
   0x0000000000400564 <+20>:	cmpq   $0x12345671,0x18(%rsp)

with debug info:

00000070 0000000000000018 00000044 FDE cie=00000030 pc=0000000000400550..00000000004005b7
  DW_CFA_advance_loc: 1 to 0000000000400551
  DW_CFA_def_cfa_offset: 24 
  DW_CFA_offset: r5 (rdi) at cfa-24
  DW_CFA_advance_loc: 4 to 0000000000400555
  DW_CFA_def_cfa_offset: 32 
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

Somehow -flto -O2 generates the incorrect debug info.
Comment 16 H.J. Lu 2017-07-27 00:48:27 UTC
The problem is in create_cie_data:

 /* On entry, the Canonical Frame Address is at SP.  */
  memset (&loc, 0, sizeof (loc));
  loc.reg = dw_stack_pointer_regnum;
  loc.offset = INCOMING_FRAME_SP_OFFSET;
  def_cfa_1 (&loc);

We lost the function type info with LTO.
Comment 17 H.J. Lu 2017-07-27 01:20:08 UTC
(In reply to H.J. Lu from comment #16)
> The problem is in create_cie_data:
> 
>  /* On entry, the Canonical Frame Address is at SP.  */
>   memset (&loc, 0, sizeof (loc));
>   loc.reg = dw_stack_pointer_regnum;
>   loc.offset = INCOMING_FRAME_SP_OFFSET;
>   def_cfa_1 (&loc);
> 
> We lost the function type info with LTO.

We didn't lose the info. The problem is that create_pseudo_cfg assumes
INCOMING_FRAME_SP_OFFSET is a constant.
Comment 18 H.J. Lu 2017-07-27 01:29:18 UTC
(In reply to H.J. Lu from comment #17)
> 
> We didn't lose the info. The problem is that create_pseudo_cfg assumes
> INCOMING_FRAME_SP_OFFSET is a constant.

I opened PR 81570.
Comment 19 hjl@gcc.gnu.org 2017-07-30 14:11:08 UTC
Author: hjl
Date: Sun Jul 30 14:10:32 2017
New Revision: 250721

URL: https://gcc.gnu.org/viewcvs?rev=250721&root=gcc&view=rev
Log:
i386: Update INCOMING_FRAME_SP_OFFSET for exception handler

Since there is an extra error code passed to the exception handler,
INCOMING_FRAME_SP_OFFSET is return address plus error code for the
exception handler.  This patch updates INCOMING_FRAME_SP_OFFSET to
the correct value for the exception handler.

This patch exposed a bug in DWARF stack frame CFI generation, which
assumes that INCOMING_FRAME_SP_OFFSET is the same for all functions:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81570

It sets and caches the incoming stack frame offset with the same
INCOMING_FRAME_SP_OFFSET for all functions.  When there are both
exception handler and normal function in the same input, the wrong
incoming stack frame offset is used for exception handler or normal
function, which leads to

FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 error == 0x12345670
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->ip == 0x12345671
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->cs == 0x12345672
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->flags == 0x12345673
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->sp == 0x12345674
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->ss == 0x12345675

With the patch for PR 81570:

https://gcc.gnu.org/ml/gcc-patches/2017-07/msg01851.html

applied, there are no regressions on i686 and x86-64.

gcc/

	PR target/79793
	* config/i386/i386.c (ix86_function_arg): Update arguments for
	exception handler.
	(ix86_compute_frame_layout): Set the initial stack offset to
	INCOMING_FRAME_SP_OFFSET.  Update red-zone offset with
	INCOMING_FRAME_SP_OFFSET.
	(ix86_expand_epilogue): Don't pop the 'ERROR_CODE' off the
	stack before exception handler returns.
	* config/i386/i386.h (INCOMING_FRAME_SP_OFFSET): Add the
	the 'ERROR_CODE' for exception handler.

gcc/testsuite/

	PR target/79793
	* gcc.dg/guality/pr68037-1.c: Update gdb breakpoints.
	* gcc.target/i386/interrupt-5.c (interrupt_frame): New struct.
	(foo): Check the builtin return address against the return address
	in interrupt frame.
	* gcc.target/i386/pr79793-1.c: New test.
	* gcc.target/i386/pr79793-2.c: Likewise.

Added:
    trunk/gcc/testsuite/gcc.target/i386/pr79793-1.c
    trunk/gcc/testsuite/gcc.target/i386/pr79793-2.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.c
    trunk/gcc/config/i386/i386.h
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/guality/pr68037-1.c
    trunk/gcc/testsuite/gcc.target/i386/interrupt-5.c
Comment 20 H.J. Lu 2017-07-30 14:11:49 UTC
Fixed for GCC 8.
Comment 21 Aldy Hernandez 2017-09-13 16:05:51 UTC
Author: aldyh
Date: Wed Sep 13 16:05:20 2017
New Revision: 252181

URL: https://gcc.gnu.org/viewcvs?rev=252181&root=gcc&view=rev
Log:
i386: Update INCOMING_FRAME_SP_OFFSET for exception handler

Since there is an extra error code passed to the exception handler,
INCOMING_FRAME_SP_OFFSET is return address plus error code for the
exception handler.  This patch updates INCOMING_FRAME_SP_OFFSET to
the correct value for the exception handler.

This patch exposed a bug in DWARF stack frame CFI generation, which
assumes that INCOMING_FRAME_SP_OFFSET is the same for all functions:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81570

It sets and caches the incoming stack frame offset with the same
INCOMING_FRAME_SP_OFFSET for all functions.  When there are both
exception handler and normal function in the same input, the wrong
incoming stack frame offset is used for exception handler or normal
function, which leads to

FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 error == 0x12345670
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->ip == 0x12345671
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->cs == 0x12345672
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->flags == 0x12345673
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->sp == 0x12345674
FAIL: gcc.dg/guality/pr68037-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  line 33 frame->ss == 0x12345675

With the patch for PR 81570:

https://gcc.gnu.org/ml/gcc-patches/2017-07/msg01851.html

applied, there are no regressions on i686 and x86-64.

gcc/

	PR target/79793
	* config/i386/i386.c (ix86_function_arg): Update arguments for
	exception handler.
	(ix86_compute_frame_layout): Set the initial stack offset to
	INCOMING_FRAME_SP_OFFSET.  Update red-zone offset with
	INCOMING_FRAME_SP_OFFSET.
	(ix86_expand_epilogue): Don't pop the 'ERROR_CODE' off the
	stack before exception handler returns.
	* config/i386/i386.h (INCOMING_FRAME_SP_OFFSET): Add the
	the 'ERROR_CODE' for exception handler.

gcc/testsuite/

	PR target/79793
	* gcc.dg/guality/pr68037-1.c: Update gdb breakpoints.
	* gcc.target/i386/interrupt-5.c (interrupt_frame): New struct.
	(foo): Check the builtin return address against the return address
	in interrupt frame.
	* gcc.target/i386/pr79793-1.c: New test.
	* gcc.target/i386/pr79793-2.c: Likewise.

Added:
    branches/range-gen2/gcc/testsuite/gcc.target/i386/pr79793-1.c
    branches/range-gen2/gcc/testsuite/gcc.target/i386/pr79793-2.c
Modified:
    branches/range-gen2/gcc/ChangeLog
    branches/range-gen2/gcc/config/i386/i386.c
    branches/range-gen2/gcc/config/i386/i386.h
    branches/range-gen2/gcc/testsuite/ChangeLog
    branches/range-gen2/gcc/testsuite/gcc.dg/guality/pr68037-1.c
    branches/range-gen2/gcc/testsuite/gcc.target/i386/interrupt-5.c