aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-06-06 17:02:22 +0000
committerDavid S. Miller <davem@gcc.gnu.org>2017-06-06 10:02:22 -0700
commit100d0700a81ba6cc9cc4910c1fb8de8e53e23d1f (patch)
tree437601299aaae6cf617c03b21cb51c297a9c8856
parent23b0f9f81d16e8fd30c79c67ea2142af3b6cf590 (diff)
downloadgcc-100d0700a81ba6cc9cc4910c1fb8de8e53e23d1f.zip
gcc-100d0700a81ba6cc9cc4910c1fb8de8e53e23d1f.tar.gz
gcc-100d0700a81ba6cc9cc4910c1fb8de8e53e23d1f.tar.bz2
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. From-SVN: r248926
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/sparc/sparc.c3
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/sparc/sparc-ret-3.c53
4 files changed, 66 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a2877ac..a394bcb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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):
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/ChangeLog b/gcc/testsuite/ChangeLog
index 70179fa..8b45627 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
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" } } */