From: Eric Botcazou <ebotca...@adacore.com>
Date: Sun, 04 Jun 2017 10:32:47 +0200

>> This is an attempt to fix PR target/80968.  This bug has existed
>> basically forever.
>> 
>> The stack_tie sequence seems to be how other targets deal with this
>> issue.  I only emit this when alloca is used.  If there are other
>> conditions that potentially would necessitate such a barrier, just let
>> me know.
> 
> See my comment in the audit trail about the stack tie approach, let's just 
> emit a frame_blockage instead.

That seems to work as well, following is going through a testsuite
run right now:

====================
[PATCH] sparc: Fix stack references in return delay slot.

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.
---
 gcc/config/sparc/sparc.c                     |  3 ++
 gcc/testsuite/gcc.target/sparc/sparc-ret-3.c | 53 ++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/sparc/sparc-ret-3.c

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 6dfb269..95a64a4 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -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
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
index 0000000..7a151f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sparc/sparc-ret-3.c
@@ -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" } } */
-- 
2.1.2.532.g19b5d50

Reply via email to