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-rh1469697-21.patch | |
parent | 5d624aa0d36abe76a344f0593eae5cf36d083b15 (diff) |
automatic import of compat-libgfortran-48openeuler24.03_LTSopeneuler23.09
Diffstat (limited to 'gcc48-rh1469697-21.patch')
-rw-r--r-- | gcc48-rh1469697-21.patch | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/gcc48-rh1469697-21.patch b/gcc48-rh1469697-21.patch new file mode 100644 index 0000000..0c694cc --- /dev/null +++ b/gcc48-rh1469697-21.patch @@ -0,0 +1,144 @@ + PR middle-end/83654 + * explow.c (anti_adjust_stack_and_probe_stack_clash): Test a + non-constant residual for zero at runtime and avoid probing in + that case. Reorganize code for trailing problem to mirror handling + of the residual. + + PR middle-end/83654 + * gcc.target/i386/stack-check-18.c: New test. + * gcc.target/i386/stack-check-19.c: New test. + +diff --git a/gcc/explow.c b/gcc/explow.c +index b6c56602152..042e71904ec 100644 +--- a/gcc/explow.c ++++ b/gcc/explow.c +@@ -1997,11 +1997,27 @@ anti_adjust_stack_and_probe_stack_clash (rtx size) + + if (residual != CONST0_RTX (Pmode)) + { ++ rtx label = NULL_RTX; ++ /* RESIDUAL could be zero at runtime and in that case *sp could ++ hold live data. Furthermore, we do not want to probe into the ++ red zone. ++ ++ Go ahead and just guard the probe at *sp on RESIDUAL != 0 at ++ runtime if RESIDUAL is not a compile time constant. */ ++ if (!CONST_INT_P (residual)) ++ { ++ label = gen_label_rtx (); ++ emit_cmp_and_jump_insns (residual, CONST0_RTX (GET_MODE (residual)), ++ EQ, NULL_RTX, Pmode, 1, label); ++ } ++ + rtx x = force_reg (Pmode, plus_constant (Pmode, residual, + -GET_MODE_SIZE (word_mode))); + anti_adjust_stack (residual); + emit_stack_probe (gen_rtx_PLUS (Pmode, stack_pointer_rtx, x)); + emit_insn (gen_blockage ()); ++ if (!CONST_INT_P (residual)) ++ emit_label (label); + } + + /* Some targets make optimistic assumptions in their prologues about +@@ -2014,28 +2030,20 @@ anti_adjust_stack_and_probe_stack_clash (rtx size) + live data. Furthermore, we don't want to probe into the red + zone. + +- Go ahead and just guard a probe at *sp on SIZE != 0 at runtime ++ Go ahead and just guard the probe at *sp on SIZE != 0 at runtime + if SIZE is not a compile time constant. */ +- +- /* Ideally we would just probe at *sp. However, if SIZE is not +- a compile-time constant, but is zero at runtime, then *sp +- might hold live data. So probe at *sp if we know that +- an allocation was made, otherwise probe into the red zone +- which is obviously undesirable. */ +- if (CONST_INT_P (size)) +- { +- emit_stack_probe (stack_pointer_rtx); +- emit_insn (gen_blockage ()); +- } +- else ++ rtx label = NULL_RTX; ++ if (!CONST_INT_P (size)) + { +- rtx label = gen_label_rtx (); ++ label = gen_label_rtx (); + emit_cmp_and_jump_insns (size, CONST0_RTX (GET_MODE (size)), + EQ, NULL_RTX, Pmode, 1, label); +- emit_stack_probe (stack_pointer_rtx); +- emit_insn (gen_blockage ()); +- emit_label (label); + } ++ ++ emit_stack_probe (stack_pointer_rtx); ++ emit_insn (gen_blockage ()); ++ if (!CONST_INT_P (size)) ++ emit_label (label); + } + } + +diff --git a/gcc/testsuite/gcc.target/i386/stack-check-18.c b/gcc/testsuite/gcc.target/i386/stack-check-18.c +new file mode 100644 +index 00000000000..6dbff4402da +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/stack-check-18.c +@@ -0,0 +1,23 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fstack-clash-protection -mtune=generic -fdump-rtl-expand" } */ ++/* { dg-require-effective-target supports_stack_clash_protection } */ ++ ++int f1 (char *); ++ ++int ++f2 (void) ++{ ++ const int size = 4096; ++ char buffer[size]; ++ return f1 (buffer); ++} ++ ++/* So we want to verify that at expand time that we probed the main ++ VLA allocation as well as the residuals. Then we want to verify ++ there was only one probe in the final assembly (implying the ++ residual probe was optimized away). */ ++/* { dg-final { scan-rtl-dump-times "allocation and probing in loop" 1 "expand" } } */ ++/* { dg-final { scan-rtl-dump-times "allocation and probing residuals" 1 "expand" } } */ ++ ++/* { dg-final { scan-assembler-times "or\[ql\]" 1 } } */ ++ +diff --git a/gcc/testsuite/gcc.target/i386/stack-check-19.c b/gcc/testsuite/gcc.target/i386/stack-check-19.c +new file mode 100644 +index 00000000000..b92c126d57f +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/stack-check-19.c +@@ -0,0 +1,29 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fstack-clash-protection -mtune=generic -fdump-rtl-expand" } */ ++/* { dg-require-effective-target supports_stack_clash_protection } */ ++ ++int f1 (char *); ++ ++int ++f2 (const int size) ++{ ++ char buffer[size]; ++ return f1 (buffer); ++} ++ ++/* So we want to verify that at expand time that we probed the main ++ VLA allocation as well as the residuals. Then we want to verify ++ there are two probes in the final assembly code. */ ++/* { dg-final { scan-rtl-dump-times "allocation and probing in loop" 1 "expand" } } */ ++/* { dg-final { scan-rtl-dump-times "allocation and probing residuals" 1 "expand" } } */ ++/* { dg-final { scan-assembler-times "or\[ql\]" 2 } } */ ++ ++/* We also want to verify (indirectly) that the residual probe is ++ guarded. We do that by checking the number of conditional ++ branches. There should be 3. One that bypasses the probe loop, one ++ in the probe loop and one that bypasses the residual probe. ++ ++ These will all be equality tests. */ ++/* { dg-final { scan-assembler-times "(\?:je|jne)" 3 } } */ ++ ++ |