diff options
| author | CoprDistGit <infra@openeuler.org> | 2024-08-01 14:23:42 +0000 | 
|---|---|---|
| committer | CoprDistGit <infra@openeuler.org> | 2024-08-01 14:23:42 +0000 | 
| commit | 82711f6567ef069eebb942e382e2c3fa61fbf538 (patch) | |
| tree | 22200b7326b32ca672ffb6e4ce6d19a09dc476e5 /gcc48-rh1537828-4.patch | |
| parent | 5d624aa0d36abe76a344f0593eae5cf36d083b15 (diff) | |
automatic import of compat-libgfortran-48openeuler24.03_LTSopeneuler23.09
Diffstat (limited to 'gcc48-rh1537828-4.patch')
| -rw-r--r-- | gcc48-rh1537828-4.patch | 182 | 
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; ++} ++ ++ | 
