diff mbox

[i386] : Fix PR69140, stack alignment + O1 breaks with Microsoft ABI

Message ID CAFULd4Zogt9Wn0tdkPW3KrL_8zKjCpE9JYPc2jB=cbb4CkgoQw@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Jan. 6, 2016, 8:16 p.m. UTC
Hello!

Attached patch fixes a failure, where no base register can be found to
save the remaining SSE (and integer) registers to stack. Since we are
able to restore registers in the prollogue using:

  m->fs.sp_valid = (!frame_pointer_needed
   || (crtl->sp_is_unchanging
&& !stack_realign_fp));

we can use similar approach at the end of the ix86_expand_prologue:

  m->fs.sp_valid = !frame_pointer_needed;

This way, we will always use frame pointer, if one is available or if
frame pointer is not available, the (realigned) stack register for
saves.

2016-01-06  Uros Bizjak  <ubizjak@gmail.com>

    PR target/69140
    * config/i386/i386.c (ix86_expand_prologue): Declare fs.sp_valid
    depending on frame_pointer_needed before remaining integer and SSE
    registers are saved.

testsuite/ChangeLog:

2016-01-06  Uros Bizjak  <ubizjak@gmail.com>

    PR target/69140
    * gcc.target/i386/pr69140.c: New test

Patch was bootstrapped and regression tested on x86_64-linux-gnu for
all default languages, Obj-C++ and Go. The patch was also tested by
the reporter by building and running Wine without problems.

I have to admit that prologue generation is hard to test, since it has
many different code paths. I guess committing the one-liner in the
hope that it won't break some target is the best approach one can do.

So, the patch was committed to mainline. I plan to backport it to
gcc-5 branch after a week or two without problems in mainline.

Uros.

Comments

Eric Botcazou Jan. 6, 2016, 11:13 p.m. UTC | #1
> Patch was bootstrapped and regression tested on x86_64-linux-gnu for
> all default languages, Obj-C++ and Go. The patch was also tested by
> the reporter by building and running Wine without problems.
> 
> I have to admit that prologue generation is hard to test, since it has
> many different code paths. I guess committing the one-liner in the
> hope that it won't break some target is the best approach one can do.

Thanks for devising the fix!
diff mbox

Patch

Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 232102)
+++ config/i386/i386.c	(working copy)
@@ -13065,6 +13065,8 @@  ix86_expand_prologue (void)
       m->fs.fp_valid = true;
     }
 
+  m->fs.sp_valid = !frame_pointer_needed;
+
   if (!int_registers_saved)
     ix86_emit_save_regs_using_mov (frame.reg_save_offset);
   if (!sse_registers_saved)
Index: testsuite/gcc.target/i386/pr69140.c
===================================================================
--- testsuite/gcc.target/i386/pr69140.c	(nonexistent)
+++ testsuite/gcc.target/i386/pr69140.c	(working copy)
@@ -0,0 +1,22 @@ 
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -mincoming-stack-boundary=3" } */
+
+typedef struct {
+  unsigned int buf[4];
+  unsigned char in[64];
+} MD4_CTX;
+
+static void MD4Transform(unsigned int buf[4], const unsigned int in[16])
+{
+  unsigned int a, b, c, d;
+  (b) += ((((c)) & ((d))) | ((~(c)) & ((a)))) + (in[7]);
+  (a) += ((((b)) & ((c))) | ((~(b)) & ((d)))) + (in[8]);
+  (d) += ((((a)) & ((b))) | ((~(a)) & ((c)))) + (in[9]);
+  buf[3] += d;
+}
+
+void __attribute__((ms_abi)) MD4Update( MD4_CTX *ctx, const unsigned char *buf)
+{
+  MD4Transform( ctx->buf, (unsigned int *)ctx->in);
+  MD4Transform( ctx->buf, (unsigned int *)ctx->in);
+}