sparc: Fix stack references in return delay slot.
authorDavid S. Miller <davem@davemloft.net>
Tue, 6 Jun 2017 17:02:22 +0000 (17:02 +0000)
committerDavid S. Miller <davem@gcc.gnu.org>
Tue, 6 Jun 2017 17:02:22 +0000 (10:02 -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: r248926

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 a2877ac51ad3d5f5b67a906e744a3f1c52458deb..a394bcbb1f061b2bda86066407b5b5c50eadf308 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-06  Maxim Kuvyrkov  <maxim.kuvyrkov@linaro.org>
 
         * tree-ssa-loop-prefetch.c (struct mem_ref_group, struct mem_ref):
index 6dfb2698c71e3924add1a8b6fb623c5bb4ed17da..95a64a41f987ee60b27d0ef9662aca853dc8cade 100644 (file)
@@ -5792,6 +5792,9 @@ sparc_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 70179fab05063b1d981d78fc35816635d656ec4e..8b456276571039eebed9e805502003a5b142fc06 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-06-06  Tom de Vries  <tom@codesourcery.com>
 
        * gcc.c-torture/compile/20000326-2.c: Use dg-require-effective-target
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" } } */