summaryrefslogtreecommitdiff
path: root/gcc48-rh1537828-4.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-08-01 14:23:42 +0000
committerCoprDistGit <infra@openeuler.org>2024-08-01 14:23:42 +0000
commit82711f6567ef069eebb942e382e2c3fa61fbf538 (patch)
tree22200b7326b32ca672ffb6e4ce6d19a09dc476e5 /gcc48-rh1537828-4.patch
parent5d624aa0d36abe76a344f0593eae5cf36d083b15 (diff)
automatic import of compat-libgfortran-48openeuler24.03_LTSopeneuler23.09
Diffstat (limited to 'gcc48-rh1537828-4.patch')
-rw-r--r--gcc48-rh1537828-4.patch182
1 files changed, 182 insertions, 0 deletions
diff --git a/gcc48-rh1537828-4.patch b/gcc48-rh1537828-4.patch
new file mode 100644
index 0000000..4750f19
--- /dev/null
+++ b/gcc48-rh1537828-4.patch
@@ -0,0 +1,182 @@
+commit 14041afe24556efd5845564aa183b6451fd9d6cc
+Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Thu Feb 1 16:22:56 2018 +0000
+
+ PR target/84128
+ * config/i386/i386.c (release_scratch_register_on_entry): Add new
+ OFFSET and RELEASE_VIA_POP arguments. Use SP+OFFSET to restore
+ the scratch if RELEASE_VIA_POP is false.
+ (ix86_adjust_stack_and_probe_stack_clash): Un-constify SIZE.
+ If we have to save a temporary register, decrement SIZE appropriately.
+ Pass new arguments to release_scratch_register_on_entry.
+ (ix86_adjust_stack_and_probe): Likewise.
+ (ix86_emit_probe_stack_range): Pass new arguments to
+ release_scratch_register_on_entry.
+
+ PR target/84128
+ * gcc.target/i386/pr84128.c: New test.
+
+diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
+index 2fe2a0c..c25d26c 100644
+--- a/gcc/config/i386/i386.c
++++ b/gcc/config/i386/i386.c
+@@ -10182,22 +10182,39 @@ get_scratch_register_on_entry (struct scratch_reg *sr)
+ }
+ }
+
+-/* Release a scratch register obtained from the preceding function. */
++/* Release a scratch register obtained from the preceding function.
++
++ If RELEASE_VIA_POP is true, we just pop the register off the stack
++ to release it. This is what non-Linux systems use with -fstack-check.
++
++ Otherwise we use OFFSET to locate the saved register and the
++ allocated stack space becomes part of the local frame and is
++ deallcated by the epilogue. */
+
+ static void
+-release_scratch_register_on_entry (struct scratch_reg *sr)
++release_scratch_register_on_entry (struct scratch_reg *sr, HOST_WIDE_INT offset,
++ bool release_via_pop)
+ {
+ if (sr->saved)
+ {
+- struct machine_function *m = cfun->machine;
+- rtx x, insn = emit_insn (gen_pop (sr->reg));
++ if (release_via_pop)
++ {
++ struct machine_function *m = cfun->machine;
++ rtx x, insn = emit_insn (gen_pop (sr->reg));
+
+- /* The RTX_FRAME_RELATED_P mechanism doesn't know about pop. */
+- RTX_FRAME_RELATED_P (insn) = 1;
+- x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (UNITS_PER_WORD));
+- x = gen_rtx_SET (VOIDmode, stack_pointer_rtx, x);
+- add_reg_note (insn, REG_FRAME_RELATED_EXPR, x);
+- m->fs.sp_offset -= UNITS_PER_WORD;
++ /* The RTX FRAME_RELATED_P mechanism doesn't know about pop. */
++ RTX_FRAME_RELATED_P (insn) = 1;
++ x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (UNITS_PER_WORD));
++ x = gen_rtx_SET (VOIDmode, stack_pointer_rtx, x);
++ add_reg_note (insn, REG_FRAME_RELATED_EXPR, x);
++ m->fs.sp_offset -= UNITS_PER_WORD;
++ }
++ else
++ {
++ rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
++ x = gen_rtx_SET (VOIDmode, sr->reg, gen_rtx_MEM (word_mode, x));
++ emit_insn (x);
++ }
+ }
+ }
+
+@@ -10212,7 +10229,7 @@ release_scratch_register_on_entry (struct scratch_reg *sr)
+ pushed on the stack. */
+
+ static void
+-ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size,
++ix86_adjust_stack_and_probe_stack_clash (HOST_WIDE_INT size,
+ const bool int_registers_saved)
+ {
+ struct machine_function *m = cfun->machine;
+@@ -10331,6 +10348,12 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size,
+ struct scratch_reg sr;
+ get_scratch_register_on_entry (&sr);
+
++ /* If we needed to save a register, then account for any space
++ that was pushed (we are not going to pop the register when
++ we do the restore). */
++ if (sr.saved)
++ size -= UNITS_PER_WORD;
++
+ /* Step 1: round SIZE down to a multiple of the interval. */
+ HOST_WIDE_INT rounded_size = size & -probe_interval;
+
+@@ -10379,7 +10402,9 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size,
+ m->fs.cfa_reg == stack_pointer_rtx);
+ dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size);
+
+- release_scratch_register_on_entry (&sr);
++ /* This does not deallocate the space reserved for the scratch
++ register. That will be deallocated in the epilogue. */
++ release_scratch_register_on_entry (&sr, size, false);
+ }
+
+ /* Make sure nothing is scheduled before we are done. */
+@@ -10392,7 +10417,7 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size,
+ pushed on the stack. */
+
+ static void
+-ix86_adjust_stack_and_probe (const HOST_WIDE_INT size,
++ix86_adjust_stack_and_probe (HOST_WIDE_INT size,
+ const bool int_registers_saved)
+ {
+ /* We skip the probe for the first interval + a small dope of 4 words and
+@@ -10465,6 +10490,11 @@ ix86_adjust_stack_and_probe (const HOST_WIDE_INT size,
+
+ get_scratch_register_on_entry (&sr);
+
++ /* If we needed to save a register, then account for any space
++ that was pushed (we are not going to pop the register when
++ we do the restore). */
++ if (sr.saved)
++ size -= UNITS_PER_WORD;
+
+ /* Step 1: round SIZE to the previous multiple of the interval. */
+
+@@ -10516,7 +10546,9 @@ ix86_adjust_stack_and_probe (const HOST_WIDE_INT size,
+ (get_probe_interval ()
+ + dope))));
+
+- release_scratch_register_on_entry (&sr);
++ /* This does not deallocate the space reserved for the scratch
++ register. That will be deallocated in the epilogue. */
++ release_scratch_register_on_entry (&sr, size, false);
+ }
+
+ gcc_assert (cfun->machine->fs.cfa_reg != stack_pointer_rtx);
+@@ -10669,7 +10701,7 @@ ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size,
+ sr.reg),
+ rounded_size - size));
+
+- release_scratch_register_on_entry (&sr);
++ release_scratch_register_on_entry (&sr, size, true);
+ }
+
+ /* Make sure nothing is scheduled before we are done. */
+diff --git a/gcc/testsuite/gcc.target/i386/pr84128.c b/gcc/testsuite/gcc.target/i386/pr84128.c
+new file mode 100644
+index 0000000..a8323fd
+--- /dev/null
++++ b/gcc/testsuite/gcc.target/i386/pr84128.c
+@@ -0,0 +1,30 @@
++/* { dg-do run } */
++/* { dg-options "-O2 -march=i686 -mtune=generic -fstack-clash-protection" } */
++/* { dg-require-effective-target ia32 } */
++
++__attribute__ ((noinline, noclone, weak, regparm (3)))
++int
++f1 (long arg0, int (*pf) (long, void *))
++{
++ unsigned char buf[32768];
++ return pf (arg0, buf);
++}
++
++__attribute__ ((noinline, noclone, weak))
++int
++f2 (long arg0, void *ignored)
++{
++ if (arg0 != 17)
++ __builtin_abort ();
++ return 19;
++}
++
++int
++main (void)
++{
++ if (f1 (17, f2) != 19)
++ __builtin_abort ();
++ return 0;
++}
++
++