]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
sparc: Fix stack references in return delay slot.
authorDavid S. Miller <davem@davemloft.net>
Tue, 6 Jun 2017 18:54:55 +0000 (18:54 +0000)
committerDavid S. Miller <davem@gcc.gnu.org>
Tue, 6 Jun 2017 18:54:55 +0000 (11:54 -0700)
gcc/

PR target/80968
* config/sparc/sparc.c (sparc_expand_prologue): Emit frame
blockage if function uses alloca.

gcc/testsuite/

* gcc.target/sparc/sparc-ret-3.c: New test.

From-SVN: r248931

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sparc/sparc-ret-3.c [new file with mode: 0644]

index 9603d68163e4348248a0e8ae56e06652a66a5a76..e5940d0d2abcdedd2812d060febd41e849da19de 100644 (file)
@@ -1,3 +1,9 @@
+2017-06-06  David S. Miller  <davem@davemloft.net>
+
+       PR target/80968
+       * config/sparc/sparc.c (sparc_expand_prologue): Emit frame
+       blockage if function uses alloca.
+
 2017-06-01  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
index 18bacf27df7833502ada73b1ed349868a9e9a979..8200a863105eeeb45f5ece787fc1d1bc9a02b0e5 100644 (file)
@@ -5790,6 +5790,9 @@ sparc_flat_expand_epilogue (bool for_eh)
 {
   HOST_WIDE_INT size = sparc_frame_size;
 
+  if (cfun->calls_alloca)
+    emit_insn (gen_frame_blockage ());
+
   if (sparc_n_global_fp_regs > 0)
     emit_save_or_restore_global_fp_regs (sparc_frame_base_reg,
                                         sparc_frame_base_offset
index 930ceb1d97b460038c63c445261bd929a5007872..12c9260ef2f1c4419dd8f3f94a85444831d3b4e5 100644 (file)
@@ -1,3 +1,7 @@
+2017-06-06  David S. Miller  <davem@davemloft.net>
+
+       * gcc.target/sparc/sparc-ret-3.c: New test.
+
 2017-05-30  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
diff --git a/gcc/testsuite/gcc.target/sparc/sparc-ret-3.c b/gcc/testsuite/gcc.target/sparc/sparc-ret-3.c
new file mode 100644 (file)
index 0000000..7a151f8
--- /dev/null
@@ -0,0 +1,53 @@
+/* PR target/80968 */
+/* { dg-do compile } */
+/* { dg-skip-if "no register windows" { *-*-* } { "-mflat" } { "" } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-mcpu=ultrasparc -O" } */
+
+/* Make sure references to the stack frame do not slip into the delay slot
+   of a return instruction.  */
+
+struct crypto_shash {
+       unsigned int descsize;
+};
+struct crypto_shash *tfm;
+
+struct shash_desc {
+       struct crypto_shash *tfm;
+       unsigned int flags;
+
+       void *__ctx[] __attribute__((aligned(8)));
+};
+
+static inline unsigned int crypto_shash_descsize(struct crypto_shash *tfm)
+{
+       return tfm->descsize;
+}
+
+static inline void *shash_desc_ctx(struct shash_desc *desc)
+{
+       return desc->__ctx;
+}
+
+#define SHASH_DESC_ON_STACK(shash, ctx)                                  \
+       char __##shash##_desc[sizeof(struct shash_desc) +         \
+                             crypto_shash_descsize(ctx)] __attribute__((aligned(8))); \
+       struct shash_desc *shash = (struct shash_desc *)__##shash##_desc
+
+extern int crypto_shash_update(struct shash_desc *, const void *, unsigned int);
+
+unsigned int bug(unsigned int crc, const void *address, unsigned int length)
+{
+       SHASH_DESC_ON_STACK(shash, tfm);
+       unsigned int *ctx = (unsigned int *)shash_desc_ctx(shash);
+       int err;
+
+       shash->tfm = tfm;
+       shash->flags = 0;
+       *ctx = crc;
+
+       err = crypto_shash_update(shash, address, length);
+
+       return *ctx;
+}
+/* { dg-final { scan-assembler "ld\[ \t\]*\\\[%i5\\+8\\\], %i0\n\[^\n\]*return\[ \t\]*%i7\\+8" } } */