[gcc r15-311] Revert "Revert "testsuite/gcc.target/cris/pr93372-2.c: Handle xpass from combine improvement""

2024-05-07 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:f6ce85502eb2e4e7bbd9b3c6c1c065a004f8f531

commit r15-311-gf6ce85502eb2e4e7bbd9b3c6c1c065a004f8f531
Author: Hans-Peter Nilsson 
Date:   Wed May 8 04:11:20 2024 +0200

Revert "Revert "testsuite/gcc.target/cris/pr93372-2.c: Handle xpass from 
combine improvement""

This reverts commit 39f81924d88e3cc197fc3df74204c9b5e01e12f7.

Diff:
---
 gcc/testsuite/gcc.target/cris/pr93372-2.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/gcc/testsuite/gcc.target/cris/pr93372-2.c 
b/gcc/testsuite/gcc.target/cris/pr93372-2.c
index 912069c018d5..2ef6471a990b 100644
--- a/gcc/testsuite/gcc.target/cris/pr93372-2.c
+++ b/gcc/testsuite/gcc.target/cris/pr93372-2.c
@@ -1,19 +1,20 @@
 /* Check that eliminable compare-instructions are eliminated. */
 /* { dg-do compile } */
 /* { dg-options "-O2" } */
-/* { dg-final { scan-assembler-not "\tcmp|\ttest" { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-not "\tnot" { xfail cc0 } } } */
-/* { dg-final { scan-assembler-not "\tlsr" { xfail cc0 } } } */
+/* { dg-final { scan-assembler-not "\tcmp|\ttest" } } */
+/* { dg-final { scan-assembler-not "\tnot" } } */
+/* { dg-final { scan-assembler-not "\tlsr" } } */
+/* We should get just one move, storing the result into *d.  */
+/* { dg-final { scan-assembler-times "\tmove" 1 } } */
 
 int f(int a, int b, int *d)
 {
   int c = a - b;
 
-  /* Whoops!  We get a cmp.d with the original operands here. */
+  /* We used to get a cmp.d with the original operands here. */
   *d = (c == 0);
 
-  /* Whoops!  While we don't get a test.d for the result here for cc0,
- we get a sequence of insns: a move, a "not" and a shift of the
- subtraction-result, where a simple "spl" would have done. */
+  /* We used to get a suboptimal sequence, but now we get the optimal "sge"
+ (a.k.a "spl") re-using flags from the subtraction. */
   return c >= 0;
 }


[gcc r15-3204] combine.cc (make_more_copies): Copy attributes from the original pseudo, PR115883

2024-08-26 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:5031df5d1f4954304c618efd2de029edc6b3699f

commit r15-3204-g5031df5d1f4954304c618efd2de029edc6b3699f
Author: Hans-Peter Nilsson 
Date:   Mon Jul 8 03:55:27 2024 +0200

combine.cc (make_more_copies): Copy attributes from the original pseudo, 
PR115883

The first of the late-combine passes, propagates some of the copies
made during the (in-time-)combine pass in make_more_copies into the
users of the "original" pseudo registers and removes the "old"
pseudos.  That effectively removes attributes such as REG_POINTER,
which matter to LRA.  The quoted PR is for an ICE-manifesting bug that
was exposed by the late-combine pass and went back to hiding with this
patch until commit r15-2937-g3673b7054ec2, the fix for PR116236, when
it was actually fixed.  To wit, this patch is only incidentally
related to that bug.

In other words, the REG_POINTER attribute should not be required for
LRA to work correctly.  This patch merely corrects state for those
propagated register-uses to ante late-combine.

For reasons not investigated, this fixes a failing test
"FAIL: gcc.dg/guality/pr54200.c -Og -DPREVENT_OPTIMIZATION line 20 z == 3"
for x86_64-linux-gnu.

PR middle-end/115883
* combine.cc (make_more_copies): Copy attributes from the original
pseudo to the new copy.

Diff:
---
 gcc/combine.cc | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/gcc/combine.cc b/gcc/combine.cc
index 40e92941e428..fef06a6cdc08 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -15102,6 +15102,12 @@ make_more_copies (void)
continue;
 
  rtx new_reg = gen_reg_rtx (GET_MODE (dest));
+
+ /* The "original" pseudo copies have important attributes
+attached, like pointerness.  We want that for these copies
+too, for use by insn recognition and later passes.  */
+ set_reg_attrs_from_value (new_reg, dest);
+
  rtx_insn *new_insn = gen_move_insn (new_reg, src);
  SET_SRC (set) = new_reg;
  emit_insn_before (new_insn, insn);


[gcc r15-3344] testsuite: Prune compilation messages for modules tests

2024-08-31 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:f22788c7c01ebb4fefffc1162eb85ffb7a82c314

commit r15-3344-gf22788c7c01ebb4fefffc1162eb85ffb7a82c314
Author: Hans-Peter Nilsson 
Date:   Sun Aug 18 07:01:06 2024 +0200

testsuite: Prune compilation messages for modules tests

All testsuite compiler-calls pass default_target_compile in the
dejagnu installation (typically /usr/share/dejagnu/target.exp) which
also calls the dejagnu-installed prune_warnings.

Normally, tests using the dg framework (most or all tests these days)
compile and link by calling various wrappers that end up calling
dg-test in the dejagnu installation, typically installed as
/usr/share/dejagnu/dg.exp.  That, besides the compiler call, also
calls ${tool}-dg-prune (g++-dg-prune) on the messages, which in turn
ends up calling prune_gcc_output in gcc/testsuite/lib/prune.exp.  That
gcc-specific "pruning" function handles more cases than the dejagnu
prune_warnings, and also has updated patterns.

But, module_do_it in modules.exp calls the lower-level
${tool}_target_compile "directly", i.e. g++_target_compile defined in
gcc/testsuite/lib/g++.exp.  That does not call ${tool}-dg-prune,
meaning those test-cases miss the gcc-specific pruning.

Noticed while testing a dejagnu update that handled the miniscule "in"
in the warning (line-breaks added below besides the original one after
"(void*)':")

"/path/to/cris-elf/bin/ld:
/gccobj/cris-elf/./libstdc++-v3/src/.libs/libstdc++.a(random.o): in
function `std::(anonymous namespace)::__libc_getentropy(void*)':
/gccsrc/libstdc++-v3/src/c++11/random.cc:183: warning: _getentropy is
not implemented and will always fail"

The line saying "in function" rather than "In function" (from the
binutils linker since 2018) is pruned by prune_gcc_output. The
prune_warnings in dejagnu-1.6.3 and earlier handles the second line
separately.  It's an unfortunate wart that neither consumes the
delimiting line-break, leaving to the callers to prune residual empty
lines.  See prune_warnings in dejagnu (default_target_compile and
dg-test) for those other line-break fixups, as alluded in the comment.

* g++.dg/modules/modules.exp (module_do_it): Prune compilation
messages.

Diff:
---
 gcc/testsuite/g++.dg/modules/modules.exp | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/gcc/testsuite/g++.dg/modules/modules.exp 
b/gcc/testsuite/g++.dg/modules/modules.exp
index 3e8df9b89309..e6bf28d8b1a0 100644
--- a/gcc/testsuite/g++.dg/modules/modules.exp
+++ b/gcc/testsuite/g++.dg/modules/modules.exp
@@ -205,9 +205,19 @@ proc module_do_it { do_what testcase std asm_list } {
 if { !$ok } {
unresolved "$ident link"
 } else {
+   global target_triplet
set out [${tool}_target_compile $asm_list \
 $execname executable $options]
eval $xfail
+
+   # Do gcc-specific pruning.
+   set out [${tool}-dg-prune $target_triplet $out]
+   # Fix up remaining line-breaks similar to "regular" pruning
+   # calls.  Otherwise, a multi-line message stripped e.g. one
+   # part by the default prune_warnings and one part part by the
+   # gcc prune_gcc_output will have a residual line-break.
+   regsub "^\[\r\n\]+" $out "" out
+
if { $out == "" } {
pass "$ident link"
} else {


[gcc r15-3439] CRIS: Add new peephole2 "lra_szext_decomposed_indir_plus"

2024-09-03 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:62dd893ff8a12a1d28f595b4e5bc43cf9f7d1c07

commit r15-3439-g62dd893ff8a12a1d28f595b4e5bc43cf9f7d1c07
Author: Hans-Peter Nilsson 
Date:   Mon Jul 8 03:59:55 2024 +0200

CRIS: Add new peephole2 "lra_szext_decomposed_indir_plus"

Exposed when running the test-suite with -flate-combine-instructions.

* config/cris/cris.md (lra_szext_decomposed_indir_plus): New
peephole2 pattern.

Diff:
---
 gcc/config/cris/cris.md | 45 +
 1 file changed, 45 insertions(+)

diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md
index c15395bd84c4..e066d5c920a9 100644
--- a/gcc/config/cris/cris.md
+++ b/gcc/config/cris/cris.md
@@ -3024,6 +3024,7 @@
 ;; Re-compose a decomposed "indirect offset" address for a szext
 ;; operation.  The non-clobbering "addi" is generated by LRA.
 ;; This and lra_szext_decomposed is covered by cris/rld-legit1.c.
+;; (Unfortunately not true when enabling late-combine.)
 (define_peephole2 ; lra_szext_decomposed_indirect_with_offset
   [(parallel
 [(set (match_operand:SI 0 "register_operand")
@@ -3046,6 +3047,50 @@
(mem:BW2 (plus:SI (szext:SI (mem:BW (match_dup 1))) (match_dup 2)
  (clobber (reg:CC CRIS_CC0_REGNUM))])])
 
+;; When enabling late-combine, we get a slightly changed register
+;; allocation.  The two allocations for the pseudo-registers involved
+;; in the matching pattern get "swapped" and the (plus ...) in the
+;; pattern above is now a load from a stack-slot.  If peephole2 is
+;; disabled, we see that the original sequence is actually improved;
+;; one less incoming instruction, a load.  We need to "undo" that
+;; improvement a bit and move that load "back" to before the sequence
+;; we combine in lra_szext_decomposed_indirect_with_offset.  But that
+;; changed again, so there's no define_peephole2 for that sequence
+;; here, because it'd be hard or impossible to write a matching
+;; test-case.  A few commits later, the incoming pattern sequence has
+;; changed again: back to the original but with the (plus...) part of
+;; the address inside the second memory reference.
+;; Coverage: cris/rld-legit1.c@r15-1880-gce34fcc572a0dc or
+;; r15-3386-gaf1500dd8c00 when adding -flate-combine-instructions.
+
+(define_peephole2 ; lra_szext_decomposed_indir_plus
+  [(parallel
+[(set (match_operand:SI 0 "register_operand")
+ (sign_extend:SI (mem:BW (match_operand:SI 1 "register_operand"
+ (clobber (reg:CC CRIS_CC0_REGNUM))])
+   (parallel
+[(set (match_operand:SI 3 "register_operand")
+ (szext:SI (mem:BW2 (plus:SI
+ (match_operand:SI 4 "register_operand")
+ (match_operand:SI 2 "register_operand")
+ (clobber (reg:CC CRIS_CC0_REGNUM))])]
+  "(REGNO (operands[0]) == REGNO (operands[3])
+|| peep2_reg_dead_p (3, operands[0]))
+   && (REGNO (operands[0]) == REGNO (operands[1])
+   || peep2_reg_dead_p (3, operands[0]))
+   && (rtx_equal_p (operands[2], operands[0])
+   || rtx_equal_p (operands[4], operands[0]))"
+  [(parallel
+[(set
+  (match_dup 3)
+  (szext:SI
+   (mem:BW2 (plus:SI (szext:SI (mem:BW (match_dup 1))) (match_dup 2)
+ (clobber (reg:CC CRIS_CC0_REGNUM))])]
+{
+  if (! rtx_equal_p (operands[4], operands[0]))
+operands[2] = operands[4];
+})
+
 ;; Add operations with similar or same decomposed addresses here, when
 ;; encountered - but only when covered by mentioned test-cases for at
 ;; least one of the cases generalized in the pattern.


[gcc r15-2024] CRIS: Disable late-combine by default, related PR115883

2024-07-13 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:a01b40c047334c5f7cf69233ac6f3bfeacc24c5d

commit r15-2024-ga01b40c047334c5f7cf69233ac6f3bfeacc24c5d
Author: Hans-Peter Nilsson 
Date:   Wed Jul 10 04:57:07 2024 +0200

CRIS: Disable late-combine by default, related PR115883

With late-combine, performance for coremark compiled for cris-elf
regresses 2.6% by performance and by size 0.4%, measured at
r15-2005-g13757e50ff0b, when compiled with "-O2 -march=v10".

Earlier, at r15-1880-gce34fcc572a0, numbers were by performance 3.2%
and by size 0.4%, even with the proposed patch to PR115883 (TL;DR: a
presumed bug in LRA or combine exposed by late-combine).  Without that
patch, about the same performance results (at that revision).
Similarly around the late-combine commit (r15-1579-g792f97b44ffc5e).

I briefly looked at the performance regression for coremark at
r15-2005-g13757e50ff0b (with/without this patch) as far as seeing that
the stack-frame grew larger (maxing out on hard registers and needing
one more slot) for at least two of the top three* functions that
regressed the most in terms of cycles per call:
matrix_mul_matrix_bitextract (in coremark, 17% slower) and __subdf3
(in libgcc, 6.7% slower).  That makes sense when considering that
late-combine "naturally" stretches register life-times.  But, looking
at late_combine::combine_into_uses and late_combine::optimizable_set,
nothing stood out to me.  I guess there's improvement opportunities in
late_combine::check_register_pressure.

(*) I opted not to look at _dtoa_r (in newlib) mostly because it's
boring and always shows up when something in gcc goes sideways.  (It
maxes out on hard registers and is big.  End of story.)

Note that the change of default is done in the
TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE worker, not in the
TARGET_OPTION_OVERRIDE worker for reasons stated in the
comment.

* config/cris/cris.cc (cris_option_override_after_change): New
function.  Disable late-combine by default.
(cris_option_override): Call the new function.

Diff:
---
 gcc/config/cris/cris.cc | 37 +
 1 file changed, 37 insertions(+)

diff --git a/gcc/config/cris/cris.cc b/gcc/config/cris/cris.cc
index f1accc0f36e5..f2c3955b9665 100644
--- a/gcc/config/cris/cris.cc
+++ b/gcc/config/cris/cris.cc
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "builtins.h"
 #include "cfgrtl.h"
 #include "tree-pass.h"
+#include "opts.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -156,6 +157,7 @@ static rtx_insn *cris_md_asm_adjust (vec &, vec &,
 HARD_REG_SET &, location_t);
 
 static void cris_option_override (void);
+static void cris_option_override_after_change ();
 
 static bool cris_frame_pointer_required (void);
 
@@ -281,6 +283,8 @@ int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION;
 
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE cris_option_override
+#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
+#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE cris_option_override_after_change
 
 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
 #define TARGET_ASM_TRAMPOLINE_TEMPLATE cris_asm_trampoline_template
@@ -2409,6 +2413,39 @@ cris_option_override (void)
 
   /* Set the per-function-data initializer.  */
   init_machine_status = cris_init_machine_status;
+
+  cris_option_override_after_change ();
+}
+
+/* The TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE worker.
+
+   The CRIS port doesn't have any port-specific function attributes to
+   handle, but to keep attributes consistent across per-function changes
+   and not fail per-function optimization settings as exposed by
+   gcc.dg/ipa/iinline-attr.c, any OPTION_SET_P work need to be done
+   here, not in the TARGET_OPTION_OVERRIDE function.  This function then
+   instead needs to called from that function.  */
+
+static void
+cris_option_override_after_change ()
+{
+  /* The combine pass inserts extra copies of the incoming parameter
+ registers in make_more_copies, between the hard registers and
+ pseudo-registers holding the "original" copies.  When doing that,
+ it does not copy attributes from those original registers.  With
+ the late-combine pass, those extra copies are propagated into more
+ places than the original copies, and trips up LRA which doesn't see
+ e.g. REG_POINTER where it's expected.  This causes an ICE for
+ gcc.target/cris/rld-legit1.c.  That's a red flag, but also a very
+ special corner case.
+
+ A more valid reason is that coremark with -march=v10 -O2 regresses
+ by X% (@r15-g vs. @r15-g and also at
+ r15-g with patches to handle the REG_POINTER and
+ rld-legit1 fallout vs. this additional change).  Disable
+ late-combine by default until that's fixed.  */
+  if (!OPTION_

[gcc r15-2025] CRIS: Fix up last comment.

2024-07-13 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:74595c778335f6c512dc38d310353dfc32c7ea95

commit r15-2025-g74595c778335f6c512dc38d310353dfc32c7ea95
Author: Hans-Peter Nilsson 
Date:   Sun Jul 14 05:15:38 2024 +0200

CRIS: Fix up last comment.

* config/cris/cris.cc (cris_option_override_after_change): Fix up
comment regarding disabling late_combine.

Diff:
---
 gcc/config/cris/cris.cc | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/gcc/config/cris/cris.cc b/gcc/config/cris/cris.cc
index f2c3955b9665..617fc0a0cb33 100644
--- a/gcc/config/cris/cris.cc
+++ b/gcc/config/cris/cris.cc
@@ -2440,10 +2440,9 @@ cris_option_override_after_change ()
  special corner case.
 
  A more valid reason is that coremark with -march=v10 -O2 regresses
- by X% (@r15-g vs. @r15-g and also at
- r15-g with patches to handle the REG_POINTER and
- rld-legit1 fallout vs. this additional change).  Disable
- late-combine by default until that's fixed.  */
+ by 2.6% @r15-2005-g13757e50ff0b compared to late-combined disabled.
+
+ Disable late-combine by default until that's fixed.  */
   if (!OPTION_SET_P (flag_late_combine_instructions))
 flag_late_combine_instructions = 0;
 }


[gcc r15-2033] CRIS: Adjust gcc.dg/tree-ssa/loop-1.c

2024-07-14 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:da37a272beceacb362373a9eab1e915db587be9e

commit r15-2033-gda37a272beceacb362373a9eab1e915db587be9e
Author: Hans-Peter Nilsson 
Date:   Mon Jul 15 04:57:06 2024 +0200

CRIS: Adjust gcc.dg/tree-ssa/loop-1.c

With r15-1619-g3b9b8d6cfdf593, there's a XPASS and a FAIL
for this test-case for cris-elf.  Looking at the generated
code, _foo is indeed no longer saved in a register for CRIS.
While that looks like a regression, coremark results are the
same around this revision, so simply adjust the test-case:
remove the target-specific exceptions for cris-*-*.

* gcc.dg/tree-ssa/loop-1.c: Remove target-specific test
and xfail to adjust for recent changes in register allocation.

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/loop-1.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c
index a531b7584a64..a8f2c3bbfdb4 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c
@@ -43,16 +43,15 @@ int xxx(void)
 /* The SH targets always use separate instructions to load the address
and to do the actual call - bsr is only generated by link time
relaxation.  */
-/* CRIS and MSP430 keep the address in a register.  */
+/* MSP430 keeps the address in a register.  */
 /* m68k sometimes puts the address in a register, depending on CPU and PIC.  */
 
-/* { dg-final { scan-assembler-times "foo" 5 { xfail hppa*-*-* ia64*-*-* 
sh*-*-* cris-*-* fido-*-* m68k-*-* i?86-*-mingw* i?86-*-cygwin* x86_64-*-mingw* 
visium-*-* nvptx*-*-* pdp11*-*-* msp430-*-* amdgcn*-*-* } } } */
+/* { dg-final { scan-assembler-times "foo" 5 { xfail hppa*-*-* ia64*-*-* 
sh*-*-* fido-*-* m68k-*-* i?86-*-mingw* i?86-*-cygwin* x86_64-*-mingw* 
visium-*-* nvptx*-*-* pdp11*-*-* msp430-*-* amdgcn*-*-* } } } */
 /* { dg-final { scan-assembler-times "foo,%r" 5 { target hppa*-*-* } } } */
 /* { dg-final { scan-assembler-times "= foo"  5 { target ia64*-*-* } } } */
 /* { dg-final { scan-assembler-times "call\[ \t\]*_foo" 5 { target 
i?86-*-mingw* i?86-*-cygwin* } } } */
 /* { dg-final { scan-assembler-times "call\[ \t\]*foo" 5 { target 
x86_64-*-mingw* } } } */
 /* { dg-final { scan-assembler-times "jsr|bsrf|blink\ttr?,r18"  5 { target 
sh*-*-* } } } */
-/* { dg-final { scan-assembler-times "Jsr \\\$r" 5 { target cris-*-* } } } */
 /* { dg-final { scan-assembler-times "\[jb\]sr" 5 { target fido-*-* m68k-*-* 
pdp11-*-* } } } */
 /* { dg-final { scan-assembler-times "bra *tr,r\[1-9\]*,r21" 5 { target 
visium-*-* } } } */
 /* { dg-final { scan-assembler-times "(?n)\[ \t\]call\[ \t\].*\[ \t\]foo," 5 { 
target nvptx*-*-* } } } */


[gcc r14-9798] testsuite/gcc.dg/debug/btf/btf-datasec-1.c: Handle leading-underscore

2024-04-04 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:3b36e86d6af3b305207c1aa6d56c2b350fefba65

commit r14-9798-g3b36e86d6af3b305207c1aa6d56c2b350fefba65
Author: Hans-Peter Nilsson 
Date:   Fri Apr 5 01:36:54 2024 +0200

testsuite/gcc.dg/debug/btf/btf-datasec-1.c: Handle leading-underscore

I noticed my autotester for cris-elf flagging this as a regression.

* gcc.dg/debug/btf/btf-datasec-1.c: Adjust pattern for targets with
symbols having a leading underscore.

Diff:
---
 gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c 
b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c
index 782216d3cb1..c8ebe5d07ca 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c
@@ -20,7 +20,7 @@
 /* { dg-final { scan-assembler-times "0xf01\[\t \]+\[^\n\]*btt_info" 1 } } 
*/
 
 /* The offset entry for each variable in a DATSEC should contain a label.  */
-/* { dg-final { scan-assembler-times 
"(?:(?:\\.4byte|\\.long|data4\\.ua|\\.ualong|\\.uaword|\\.dword|long|dc\\.l|\\.word)\[\t
 \]|\\.vbyte\t4,\[\t \]?)\[a-e\]\[\t \]+\[^\n\]*bts_offset" 5 } } */
+/* { dg-final { scan-assembler-times 
"(?:(?:\\.4byte|\\.long|data4\\.ua|\\.ualong|\\.uaword|\\.dword|long|dc\\.l|\\.word)\[\t
 \]|\\.vbyte\t4,\[\t \]?)_?\[a-e\]\[\t \]+\[^\n\]*bts_offset" 5 } } */
 /* { dg-final { scan-assembler-times "my_cstruct\[\t \]+\[^\n\]*bts_offset" 1 
} } */
 /* { dg-final { scan-assembler-times "bigarr\[\t \]+\[^\n\]*bts_offset" 1 } } 
*/


[gcc r14-9799] testsuite/gcc.target/cris/pr93372-2.c: Handle xpass from combine improvement

2024-04-04 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:4c8b3600c4856f7915281ae3ff4d97271c83a540

commit r14-9799-g4c8b3600c4856f7915281ae3ff4d97271c83a540
Author: Hans-Peter Nilsson 
Date:   Fri Apr 5 02:50:16 2024 +0200

testsuite/gcc.target/cris/pr93372-2.c: Handle xpass from combine improvement

After r14-9692-g839bc42772ba7a, a sequence that actually
looks optimal is now emitted, observed at
r14-9788-gb7bd2ec73d66f7.  This caused an XPASS for this
test.  While adjusting the test, better also guard it
against regressions by checking that there are no redundant
move insns.

That's the only test that's improved to the point of
affecting test-patterns.  E.g. pr93372-5.c (which references
pr93372-2.c) is also improved, though it retains a redundant
compare insn.  (PR 93372 was about regressions from the cc0
representation; not further improvement like here, thus it's
not tagged.  Though, I did not double-check whether this
actually *was* a regression from cc0.)

* gcc.target/cris/pr93372-2.c: Tweak scan-assembler
checks to cover recent combine improvement.

Diff:
---
 gcc/testsuite/gcc.target/cris/pr93372-2.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/gcc/testsuite/gcc.target/cris/pr93372-2.c 
b/gcc/testsuite/gcc.target/cris/pr93372-2.c
index 912069c018d..2ef6471a990 100644
--- a/gcc/testsuite/gcc.target/cris/pr93372-2.c
+++ b/gcc/testsuite/gcc.target/cris/pr93372-2.c
@@ -1,19 +1,20 @@
 /* Check that eliminable compare-instructions are eliminated. */
 /* { dg-do compile } */
 /* { dg-options "-O2" } */
-/* { dg-final { scan-assembler-not "\tcmp|\ttest" { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-not "\tnot" { xfail cc0 } } } */
-/* { dg-final { scan-assembler-not "\tlsr" { xfail cc0 } } } */
+/* { dg-final { scan-assembler-not "\tcmp|\ttest" } } */
+/* { dg-final { scan-assembler-not "\tnot" } } */
+/* { dg-final { scan-assembler-not "\tlsr" } } */
+/* We should get just one move, storing the result into *d.  */
+/* { dg-final { scan-assembler-times "\tmove" 1 } } */
 
 int f(int a, int b, int *d)
 {
   int c = a - b;
 
-  /* Whoops!  We get a cmp.d with the original operands here. */
+  /* We used to get a cmp.d with the original operands here. */
   *d = (c == 0);
 
-  /* Whoops!  While we don't get a test.d for the result here for cc0,
- we get a sequence of insns: a move, a "not" and a shift of the
- subtraction-result, where a simple "spl" would have done. */
+  /* We used to get a suboptimal sequence, but now we get the optimal "sge"
+ (a.k.a "spl") re-using flags from the subtraction. */
   return c >= 0;
 }


[gcc r14-9904] Revert "testsuite/gcc.target/cris/pr93372-2.c: Handle xpass from combine improvement"

2024-04-10 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:39f81924d88e3cc197fc3df74204c9b5e01e12f7

commit r14-9904-g39f81924d88e3cc197fc3df74204c9b5e01e12f7
Author: Hans-Peter Nilsson 
Date:   Wed Apr 10 17:24:10 2024 +0200

Revert "testsuite/gcc.target/cris/pr93372-2.c: Handle xpass from combine 
improvement"

This reverts commit 4c8b3600c4856f7915281ae3ff4d97271c83a540.

Diff:
---
 gcc/testsuite/gcc.target/cris/pr93372-2.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/gcc/testsuite/gcc.target/cris/pr93372-2.c 
b/gcc/testsuite/gcc.target/cris/pr93372-2.c
index 2ef6471a990..912069c018d 100644
--- a/gcc/testsuite/gcc.target/cris/pr93372-2.c
+++ b/gcc/testsuite/gcc.target/cris/pr93372-2.c
@@ -1,20 +1,19 @@
 /* Check that eliminable compare-instructions are eliminated. */
 /* { dg-do compile } */
 /* { dg-options "-O2" } */
-/* { dg-final { scan-assembler-not "\tcmp|\ttest" } } */
-/* { dg-final { scan-assembler-not "\tnot" } } */
-/* { dg-final { scan-assembler-not "\tlsr" } } */
-/* We should get just one move, storing the result into *d.  */
-/* { dg-final { scan-assembler-times "\tmove" 1 } } */
+/* { dg-final { scan-assembler-not "\tcmp|\ttest" { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-not "\tnot" { xfail cc0 } } } */
+/* { dg-final { scan-assembler-not "\tlsr" { xfail cc0 } } } */
 
 int f(int a, int b, int *d)
 {
   int c = a - b;
 
-  /* We used to get a cmp.d with the original operands here. */
+  /* Whoops!  We get a cmp.d with the original operands here. */
   *d = (c == 0);
 
-  /* We used to get a suboptimal sequence, but now we get the optimal "sge"
- (a.k.a "spl") re-using flags from the subtraction. */
+  /* Whoops!  While we don't get a test.d for the result here for cc0,
+ we get a sequence of insns: a move, a "not" and a shift of the
+ subtraction-result, where a simple "spl" would have done. */
   return c >= 0;
 }


[gcc r15-877] resource.cc (mark_target_live_regs): Don't look past target insn, PR115182

2024-05-28 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:84b4ed45ea81ed5c4fb656a17846b26071c23e7d

commit r15-877-g84b4ed45ea81ed5c4fb656a17846b26071c23e7d
Author: Hans-Peter Nilsson 
Date:   Tue May 28 23:15:57 2024 +0200

resource.cc (mark_target_live_regs): Don't look past target insn, PR115182

The PR115182 regression is that a delay-slot for a conditional branch,
is no longer filled with an insn that has been "sunk" because of
r15-518-g99b1daae18c095, for cris-elf w. -O2 -march=v10.

There are still sufficient "nearby" dependency-less insns that the
delay-slot shouldn't be empty.  In particular there's one candidate in
the loop, right after an off-ramp branch, off the loop: a move from
$r9 to $r3.

beq .L2
nop
move.d $r9,$r3

But, the resource.cc data-flow-analysis incorrectly says it collides
with registers "live" at that .L2 off-ramp.  The off-ramp insns
(inlined from simple_rand) look like this (left-to-right direction):

.L2:
move.d $r12,[_seed.0]
move.d $r13,[_seed.0+4]
ret
movem [$sp+],$r8

So, a store of a long long to _seed, a return instruction and a
restoring multi-register-load of r0..r8 (all callee-saved registers)
in the delay-slot of the return insn.  The return-value is kept in
$r10,$r11 so in total $r10..$r13 live plus the stack-pointer and
return-address registers.  But, mark_target_live_regs says that
$r0..$r8 are also live because it *includes the registers live for the
return instruction*!  While they "come alive" after the movem, they
certainly aren't live at the "off-ramp" .L2 label.

The problem is in mark_target_live_regs: it consults a hash-table
indexed by insn uid, where it tracks the currently live registers with
a "generation" count to handle when it moves around insn, filling
delay-slots.  As a fall-back, it starts with registers live at the
start of each basic block, calculated by the comparatively modern df
machinery (except that it can fail finding out which basic block an
insn belongs to, at which times it includes all registers film at 11),
and tracks the semantics of insns up to each insn.

You'd think that's all that should be done, but then for some reason
it *also* looks at insns *after the target insn* up to a few branches,
and includes that in the set of live registers!  This is the code in
mark_target_live_regs that starts with the call to
find_dead_or_set_registers.  I couldn't make sense of it, so I looked
at its history, and I think I found the cause; it's a thinko or
possibly two thinkos.  The original implementation, gcc-git-described
as r0-97-g9c7e297806a27f, later moved from reorg.c to resource.c in
r0-20470-gca545bb569b756.

I believe the "extra" lookup was intended to counter flaws in the
reorg.c/resource.c register liveness analysis; to inspect insns along
the execution paths to exclude registers that, when looking at
subsequent insns, weren't live.  That guess is backed by a sentence in
the updated (i.e. deleted) part of the function head comment for
mark_target_live_regs: "Next, scan forward from TARGET looking for
things set or clobbered before they are used.  These are not live."
To me that sounds like flawed register-liveness data.

An epilogue expanded as RTX (i.e. not just assembly code emitted as
text) is introduced in basepoints/gcc-0-1334-gbdac5f5848fb, so before
that time, nobody would notice that saved registers were included as
live registers in delay-slots in "next-to-last" basic blocks.

Then in r0-24783-g96e9c98d59cc40, the intersection ("and") was changed
to a union ("or"), i.e. it added to the set of live registers instead
of thinning it out.  In the gcc-patches archives, I see the patch
submission doesn't offer a C test-case and only has RTX snippets
(apparently for SPARC).  The message does admit that the change goes
"against what the comments in the code say":
https://gcc.gnu.org/pipermail/gcc-patches/1999-November/021836.html
It looks like this was related to a bug with register liveness info
messed up when moving a "delay-slotted" insn from one slot to another.
But, I can't help but thinking it's just papering over a register
liveness bug elsewhere.

I think, with a reliable "DF_LR_IN", the whole thing *after* tracking
from start-of-bb up to the target insn should be removed; thus.

This patch also removes the now-unused find_dead_or_set_registers
function.

At r15-518, it fixes the issue for CRIS and improves coremark scores
at -O2 -march=v10 a tiny bit (about 0.05%).

PR rtl-optimization/115182
* resource.cc (mark_target_live_regs): Don't look for
unconditional branches after the target to improve on the
register

[gcc r15-878] resource.cc: Replace calls to find_basic_block with cfgrtl BLOCK_FOR_INSN

2024-05-28 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:933ab59c59bdc1ac9e3ca3a56527836564e1821b

commit r15-878-g933ab59c59bdc1ac9e3ca3a56527836564e1821b
Author: Hans-Peter Nilsson 
Date:   Tue May 28 23:16:48 2024 +0200

resource.cc: Replace calls to find_basic_block with cfgrtl BLOCK_FOR_INSN

...and call compute_bb_for_insn in init_resource_info and
free_bb_for_insn in free_resource_info.

I put a gcc_unreachable in that else-clause for a failing
find_basic_block in mark_target_live_regs after the comment that says:

/* We didn't find the start of a basic block.  Assume everything
   in use.  This should happen only extremely rarely.  */
SET_HARD_REG_SET (res->regs);

and found that it fails not extremely rarely but extremely early in
the build (compiling libgcc).

That kind of pessimization leads to suboptimal delay-slot-filling.
Instead, do like many machine_dependent_reorg passes and call
compute_bb_for_insn as part of resource.cc initialization.

After this patch, there's a whole "if (b != -1)" conditional that's
dominated by a gcc_assert (b != -1).  I separated that, as it's a NFC
whitespace patch that hampers patch readability.

Altogether this improved coremark performance for CRIS at -O2
-march=v10 by 0.36%.

* resource.cc: Include cfgrtl.h.  Use BLOCK_FOR_INSN (insn)->index
instead of calling find_basic_block (insn).  Assert for not -1.
(find_basic_block): Remove function.
(init_resource_info): Call compute_bb_for_insn.
(free_resource_info): Call free_bb_for_insn.

Diff:
---
 gcc/resource.cc | 66 +
 1 file changed, 10 insertions(+), 56 deletions(-)

diff --git a/gcc/resource.cc b/gcc/resource.cc
index 06fcfd3e44c..0d8cde93570 100644
--- a/gcc/resource.cc
+++ b/gcc/resource.cc
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm_p.h"
 #include "regs.h"
 #include "emit-rtl.h"
+#include "cfgrtl.h"
 #include "resource.h"
 #include "insn-attr.h"
 #include "function-abi.h"
@@ -75,7 +76,6 @@ static HARD_REG_SET current_live_regs;
 static HARD_REG_SET pending_dead_regs;
 
 static void update_live_status (rtx, const_rtx, void *);
-static int find_basic_block (rtx_insn *, int);
 static rtx_insn *next_insn_no_annul (rtx_insn *);
 
 /* Utility function called from mark_target_live_regs via note_stores.
@@ -113,46 +113,6 @@ update_live_status (rtx dest, const_rtx x, void *data 
ATTRIBUTE_UNUSED)
CLEAR_HARD_REG_BIT (pending_dead_regs, i);
   }
 }
-
-/* Find the number of the basic block with correct live register
-   information that starts closest to INSN.  Return -1 if we couldn't
-   find such a basic block or the beginning is more than
-   SEARCH_LIMIT instructions before INSN.  Use SEARCH_LIMIT = -1 for
-   an unlimited search.
-
-   The delay slot filling code destroys the control-flow graph so,
-   instead of finding the basic block containing INSN, we search
-   backwards toward a BARRIER where the live register information is
-   correct.  */
-
-static int
-find_basic_block (rtx_insn *insn, int search_limit)
-{
-  /* Scan backwards to the previous BARRIER.  Then see if we can find a
- label that starts a basic block.  Return the basic block number.  */
-  for (insn = prev_nonnote_insn (insn);
-   insn && !BARRIER_P (insn) && search_limit != 0;
-   insn = prev_nonnote_insn (insn), --search_limit)
-;
-
-  /* The closest BARRIER is too far away.  */
-  if (search_limit == 0)
-return -1;
-
-  /* The start of the function.  */
-  else if (insn == 0)
-return ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->index;
-
-  /* See if any of the upcoming CODE_LABELs start a basic block.  If we reach
- anything other than a CODE_LABEL or note, we can't find this code.  */
-  for (insn = next_nonnote_insn (insn);
-   insn && LABEL_P (insn);
-   insn = next_nonnote_insn (insn))
-if (BLOCK_FOR_INSN (insn))
-  return BLOCK_FOR_INSN (insn)->index;
-
-  return -1;
-}
 
 /* Similar to next_insn, but ignores insns in the delay slots of
an annulled branch.  */
@@ -714,7 +674,8 @@ mark_target_live_regs (rtx_insn *insns, rtx 
target_maybe_return, struct resource
 }
 
   if (b == -1)
-b = find_basic_block (target, param_max_delay_slot_live_search);
+b = BLOCK_FOR_INSN (target)->index;
+  gcc_assert (b != -1);
 
   if (target_hash_table != NULL)
 {
@@ -722,7 +683,7 @@ mark_target_live_regs (rtx_insn *insns, rtx 
target_maybe_return, struct resource
{
  /* If the information is up-to-date, use it.  Otherwise, we will
 update it below.  */
- if (b == tinfo->block && b != -1 && tinfo->bb_tick == bb_ticks[b])
+ if (b == tinfo->block && tinfo->bb_tick == bb_ticks[b])
{
  res->regs = tinfo->live_regs;
  return;
@@ -905,7 +866,6 @@ void
 init_resource_info (rtx

[gcc r15-879] resource.cc (mark_target_live_regs): Remove check for bb not found

2024-05-28 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:e1abce5b6ad8f5aee86ec7729b516d81014db09e

commit r15-879-ge1abce5b6ad8f5aee86ec7729b516d81014db09e
Author: Hans-Peter Nilsson 
Date:   Tue May 28 23:17:31 2024 +0200

resource.cc (mark_target_live_regs): Remove check for bb not found

No functional change.

A "git diff -wb" (ignore whitespace diff) shows that this
commit just removes a "if (b != -1)" after a "gcc_assert (b
!= -1)" and also removes the subsequent "else" clause.

* resource.cc (mark_target_live_regs): Remove redundant check for b
being -1, after gcc_assert.

Diff:
---
 gcc/resource.cc | 270 +++-
 1 file changed, 132 insertions(+), 138 deletions(-)

diff --git a/gcc/resource.cc b/gcc/resource.cc
index 0d8cde93570..62bd46f786e 100644
--- a/gcc/resource.cc
+++ b/gcc/resource.cc
@@ -704,156 +704,150 @@ mark_target_live_regs (rtx_insn *insns, rtx 
target_maybe_return, struct resource
 
   CLEAR_HARD_REG_SET (pending_dead_regs);
 
-  /* If we found a basic block, get the live registers from it and update
- them with anything set or killed between its start and the insn before
- TARGET; this custom life analysis is really about registers so we need
- to use the LR problem.  Otherwise, we must assume everything is live.  */
-  if (b != -1)
+  /* Get the live registers from the basic block and update them with
+ anything set or killed between its start and the insn before
+ TARGET; this custom life analysis is really about registers so we
+ need to use the LR problem.  Otherwise, we must assume everything
+ is live.  */
+  regset regs_live = DF_LR_IN (BASIC_BLOCK_FOR_FN (cfun, b));
+  rtx_insn *start_insn, *stop_insn;
+  df_ref def;
+
+  /* Compute hard regs live at start of block.  */
+  REG_SET_TO_HARD_REG_SET (current_live_regs, regs_live);
+  FOR_EACH_ARTIFICIAL_DEF (def, b)
+if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+  SET_HARD_REG_BIT (current_live_regs, DF_REF_REGNO (def));
+
+  /* Get starting and ending insn, handling the case where each might
+ be a SEQUENCE.  */
+  start_insn = (b == ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->index ?
+   insns : BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, b)));
+  stop_insn = target;
+
+  if (NONJUMP_INSN_P (start_insn)
+  && GET_CODE (PATTERN (start_insn)) == SEQUENCE)
+start_insn = as_a  (PATTERN (start_insn))->insn (0);
+
+  if (NONJUMP_INSN_P (stop_insn)
+  && GET_CODE (PATTERN (stop_insn)) == SEQUENCE)
+stop_insn = next_insn (PREV_INSN (stop_insn));
+
+  for (insn = start_insn; insn != stop_insn;
+   insn = next_insn_no_annul (insn))
 {
-  regset regs_live = DF_LR_IN (BASIC_BLOCK_FOR_FN (cfun, b));
-  rtx_insn *start_insn, *stop_insn;
-  df_ref def;
-
-  /* Compute hard regs live at start of block.  */
-  REG_SET_TO_HARD_REG_SET (current_live_regs, regs_live);
-  FOR_EACH_ARTIFICIAL_DEF (def, b)
-   if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
- SET_HARD_REG_BIT (current_live_regs, DF_REF_REGNO (def));
-
-  /* Get starting and ending insn, handling the case where each might
-be a SEQUENCE.  */
-  start_insn = (b == ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->index ?
-   insns : BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, b)));
-  stop_insn = target;
-
-  if (NONJUMP_INSN_P (start_insn)
- && GET_CODE (PATTERN (start_insn)) == SEQUENCE)
-   start_insn = as_a  (PATTERN (start_insn))->insn (0);
-
-  if (NONJUMP_INSN_P (stop_insn)
- && GET_CODE (PATTERN (stop_insn)) == SEQUENCE)
-   stop_insn = next_insn (PREV_INSN (stop_insn));
-
-  for (insn = start_insn; insn != stop_insn;
-  insn = next_insn_no_annul (insn))
+  rtx link;
+  rtx_insn *real_insn = insn;
+  enum rtx_code code = GET_CODE (insn);
+
+  if (DEBUG_INSN_P (insn))
+   continue;
+
+  /* If this insn is from the target of a branch, it isn't going to
+be used in the sequel.  If it is used in both cases, this
+test will not be true.  */
+  if ((code == INSN || code == JUMP_INSN || code == CALL_INSN)
+ && INSN_FROM_TARGET_P (insn))
+   continue;
+
+  /* If this insn is a USE made by update_block, we care about the
+underlying insn.  */
+  if (code == INSN
+ && GET_CODE (PATTERN (insn)) == USE
+ && INSN_P (XEXP (PATTERN (insn), 0)))
+   real_insn = as_a  (XEXP (PATTERN (insn), 0));
+
+  if (CALL_P (real_insn))
{
- rtx link;
- rtx_insn *real_insn = insn;
- enum rtx_code code = GET_CODE (insn);
-
- if (DEBUG_INSN_P (insn))
-   continue;
-
- /* If this insn is from the target of a branch, it isn't going to
-be used in the sequel.  If it is used in both cases, this
-test will not be true.  */
- if ((code == INSN || code == JUMP_INSN || code == CALL_INSN)
- && INSN_FROM_TARGET_P 

[gcc r15-880] resource.cc: Remove redundant conditionals

2024-05-28 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:802a98d128f9b0eea2432f6511328d14e0bd721b

commit r15-880-g802a98d128f9b0eea2432f6511328d14e0bd721b
Author: Hans-Peter Nilsson 
Date:   Tue May 28 23:18:14 2024 +0200

resource.cc: Remove redundant conditionals

No functional change.

- We always have a target_hash_table and bb_ticks because
init_resource_info is always called.  These conditionals are
an ancient artifact: it's been quite a while since
resource.cc was used elsewhere than exclusively from reorg.cc

- In mark_target_live_regs, get rid of a now-redundant "if
(tinfo != NULL)" conditional and replace an "if (bb)" with a
gcc_assert.

A "git diff -wb" (ignore whitespace diff) is better at
showing the actual changes.

* resource.cc (free_resource_info, clear_hashed_info_for_insn): 
Don't
check for non-null target_hash_table and bb_ticks.
(mark_target_live_regs): Ditto.  Replace check for non-NULL result 
from
BLOCK_FOR_INSN with a call to gcc_assert.  Fold code conditioned on
tinfo != NULL.

Diff:
---
 gcc/resource.cc | 123 
 1 file changed, 52 insertions(+), 71 deletions(-)

diff --git a/gcc/resource.cc b/gcc/resource.cc
index 62bd46f786e..7c1de886432 100644
--- a/gcc/resource.cc
+++ b/gcc/resource.cc
@@ -658,49 +658,42 @@ mark_target_live_regs (rtx_insn *insns, rtx 
target_maybe_return, struct resource
   res->cc = 0;
 
   /* See if we have computed this value already.  */
-  if (target_hash_table != NULL)
-{
-  for (tinfo = target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME];
-  tinfo; tinfo = tinfo->next)
-   if (tinfo->uid == INSN_UID (target))
- break;
-
-  /* Start by getting the basic block number.  If we have saved
-information, we can get it from there unless the insn at the
-start of the basic block has been deleted.  */
-  if (tinfo && tinfo->block != -1
- && ! BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, tinfo->block))->deleted ())
-   b = tinfo->block;
-}
+  for (tinfo = target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME];
+   tinfo; tinfo = tinfo->next)
+if (tinfo->uid == INSN_UID (target))
+  break;
+
+  /* Start by getting the basic block number.  If we have saved
+ information, we can get it from there unless the insn at the
+ start of the basic block has been deleted.  */
+  if (tinfo && tinfo->block != -1
+  && ! BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, tinfo->block))->deleted ())
+b = tinfo->block;
 
   if (b == -1)
 b = BLOCK_FOR_INSN (target)->index;
   gcc_assert (b != -1);
 
-  if (target_hash_table != NULL)
+  if (tinfo)
 {
-  if (tinfo)
+  /* If the information is up-to-date, use it.  Otherwise, we will
+update it below.  */
+  if (b == tinfo->block && tinfo->bb_tick == bb_ticks[b])
{
- /* If the information is up-to-date, use it.  Otherwise, we will
-update it below.  */
- if (b == tinfo->block && tinfo->bb_tick == bb_ticks[b])
-   {
- res->regs = tinfo->live_regs;
- return;
-   }
-   }
-  else
-   {
- /* Allocate a place to put our results and chain it into the
-hash table.  */
- tinfo = XNEW (struct target_info);
- tinfo->uid = INSN_UID (target);
- tinfo->block = b;
- tinfo->next
-   = target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME];
- target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME] = tinfo;
+ res->regs = tinfo->live_regs;
+ return;
}
 }
+  else
+{
+  /* Allocate a place to put our results and chain it into the hash
+table.  */
+  tinfo = XNEW (struct target_info);
+  tinfo->uid = INSN_UID (target);
+  tinfo->block = b;
+  tinfo->next = target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME];
+  target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME] = tinfo;
+}
 
   CLEAR_HARD_REG_SET (pending_dead_regs);
 
@@ -825,13 +818,12 @@ mark_target_live_regs (rtx_insn *insns, rtx 
target_maybe_return, struct resource
 to be live here still are.  The fallthrough edge may have
 left a live register uninitialized.  */
  bb = BLOCK_FOR_INSN (real_insn);
- if (bb)
-   {
- HARD_REG_SET extra_live;
+ gcc_assert (bb);
 
- REG_SET_TO_HARD_REG_SET (extra_live, DF_LR_IN (bb));
- current_live_regs |= extra_live;
-   }
+ HARD_REG_SET extra_live;
+
+ REG_SET_TO_HARD_REG_SET (extra_live, DF_LR_IN (bb));
+ current_live_regs |= extra_live;
}
 
   /* The beginning of the epilogue corresponds to the end of the
@@ -847,10 +839,8 @@ mark_target_live_regs (rtx_insn *insns, rtx 
target_maybe_return, struct resource
 {
   tinfo->block = b;
   tinfo->bb

[gcc r15-914] Revert "resource.cc: Remove redundant conditionals"

2024-05-29 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:c31a9d3152d6119aab83c403308ddb933fe905c5

commit r15-914-gc31a9d3152d6119aab83c403308ddb933fe905c5
Author: Hans-Peter Nilsson 
Date:   Thu May 30 01:57:16 2024 +0200

Revert "resource.cc: Remove redundant conditionals"

This reverts commit 802a98d128f9b0eea2432f6511328d14e0bd721b.

Diff:
---
 gcc/resource.cc | 123 
 1 file changed, 71 insertions(+), 52 deletions(-)

diff --git a/gcc/resource.cc b/gcc/resource.cc
index 7c1de886432..62bd46f786e 100644
--- a/gcc/resource.cc
+++ b/gcc/resource.cc
@@ -658,41 +658,48 @@ mark_target_live_regs (rtx_insn *insns, rtx 
target_maybe_return, struct resource
   res->cc = 0;
 
   /* See if we have computed this value already.  */
-  for (tinfo = target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME];
-   tinfo; tinfo = tinfo->next)
-if (tinfo->uid == INSN_UID (target))
-  break;
-
-  /* Start by getting the basic block number.  If we have saved
- information, we can get it from there unless the insn at the
- start of the basic block has been deleted.  */
-  if (tinfo && tinfo->block != -1
-  && ! BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, tinfo->block))->deleted ())
-b = tinfo->block;
+  if (target_hash_table != NULL)
+{
+  for (tinfo = target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME];
+  tinfo; tinfo = tinfo->next)
+   if (tinfo->uid == INSN_UID (target))
+ break;
+
+  /* Start by getting the basic block number.  If we have saved
+information, we can get it from there unless the insn at the
+start of the basic block has been deleted.  */
+  if (tinfo && tinfo->block != -1
+ && ! BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, tinfo->block))->deleted ())
+   b = tinfo->block;
+}
 
   if (b == -1)
 b = BLOCK_FOR_INSN (target)->index;
   gcc_assert (b != -1);
 
-  if (tinfo)
+  if (target_hash_table != NULL)
 {
-  /* If the information is up-to-date, use it.  Otherwise, we will
-update it below.  */
-  if (b == tinfo->block && tinfo->bb_tick == bb_ticks[b])
+  if (tinfo)
{
- res->regs = tinfo->live_regs;
- return;
+ /* If the information is up-to-date, use it.  Otherwise, we will
+update it below.  */
+ if (b == tinfo->block && tinfo->bb_tick == bb_ticks[b])
+   {
+ res->regs = tinfo->live_regs;
+ return;
+   }
+   }
+  else
+   {
+ /* Allocate a place to put our results and chain it into the
+hash table.  */
+ tinfo = XNEW (struct target_info);
+ tinfo->uid = INSN_UID (target);
+ tinfo->block = b;
+ tinfo->next
+   = target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME];
+ target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME] = tinfo;
}
-}
-  else
-{
-  /* Allocate a place to put our results and chain it into the hash
-table.  */
-  tinfo = XNEW (struct target_info);
-  tinfo->uid = INSN_UID (target);
-  tinfo->block = b;
-  tinfo->next = target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME];
-  target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME] = tinfo;
 }
 
   CLEAR_HARD_REG_SET (pending_dead_regs);
@@ -818,12 +825,13 @@ mark_target_live_regs (rtx_insn *insns, rtx 
target_maybe_return, struct resource
 to be live here still are.  The fallthrough edge may have
 left a live register uninitialized.  */
  bb = BLOCK_FOR_INSN (real_insn);
- gcc_assert (bb);
-
- HARD_REG_SET extra_live;
+ if (bb)
+   {
+ HARD_REG_SET extra_live;
 
- REG_SET_TO_HARD_REG_SET (extra_live, DF_LR_IN (bb));
- current_live_regs |= extra_live;
+ REG_SET_TO_HARD_REG_SET (extra_live, DF_LR_IN (bb));
+ current_live_regs |= extra_live;
+   }
}
 
   /* The beginning of the epilogue corresponds to the end of the
@@ -839,8 +847,10 @@ mark_target_live_regs (rtx_insn *insns, rtx 
target_maybe_return, struct resource
 {
   tinfo->block = b;
   tinfo->bb_tick = bb_ticks[b];
-  tinfo->live_regs = res->regs;
 }
+
+  if (tinfo != NULL)
+tinfo->live_regs = res->regs;
 }
 
 /* Initialize the resources required by mark_target_live_regs ().
@@ -929,25 +939,31 @@ init_resource_info (rtx_insn *epilogue_insn)
 void
 free_resource_info (void)
 {
-  int i;
-
-  for (i = 0; i < TARGET_HASH_PRIME; ++i)
+  if (target_hash_table != NULL)
 {
-  struct target_info *ti = target_hash_table[i];
+  int i;
 
-  while (ti)
+  for (i = 0; i < TARGET_HASH_PRIME; ++i)
{
- struct target_info *next = ti->next;
- free (ti);
- ti = next;
+ struct target_info *ti = target_hash_table[i];
+
+ while (ti)
+   {
+ struct target_info *next = ti->next;
+ free 

[gcc r15-915] Revert "resource.cc (mark_target_live_regs): Remove check for bb not found"

2024-05-29 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:afe48a45b8baa310c8373499b1e5b5407a3e2b94

commit r15-915-gafe48a45b8baa310c8373499b1e5b5407a3e2b94
Author: Hans-Peter Nilsson 
Date:   Thu May 30 01:57:29 2024 +0200

Revert "resource.cc (mark_target_live_regs): Remove check for bb not found"

This reverts commit e1abce5b6ad8f5aee86ec7729b516d81014db09e.

Diff:
---
 gcc/resource.cc | 270 +---
 1 file changed, 138 insertions(+), 132 deletions(-)

diff --git a/gcc/resource.cc b/gcc/resource.cc
index 62bd46f786e..0d8cde93570 100644
--- a/gcc/resource.cc
+++ b/gcc/resource.cc
@@ -704,150 +704,156 @@ mark_target_live_regs (rtx_insn *insns, rtx 
target_maybe_return, struct resource
 
   CLEAR_HARD_REG_SET (pending_dead_regs);
 
-  /* Get the live registers from the basic block and update them with
- anything set or killed between its start and the insn before
- TARGET; this custom life analysis is really about registers so we
- need to use the LR problem.  Otherwise, we must assume everything
- is live.  */
-  regset regs_live = DF_LR_IN (BASIC_BLOCK_FOR_FN (cfun, b));
-  rtx_insn *start_insn, *stop_insn;
-  df_ref def;
-
-  /* Compute hard regs live at start of block.  */
-  REG_SET_TO_HARD_REG_SET (current_live_regs, regs_live);
-  FOR_EACH_ARTIFICIAL_DEF (def, b)
-if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
-  SET_HARD_REG_BIT (current_live_regs, DF_REF_REGNO (def));
-
-  /* Get starting and ending insn, handling the case where each might
- be a SEQUENCE.  */
-  start_insn = (b == ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->index ?
-   insns : BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, b)));
-  stop_insn = target;
-
-  if (NONJUMP_INSN_P (start_insn)
-  && GET_CODE (PATTERN (start_insn)) == SEQUENCE)
-start_insn = as_a  (PATTERN (start_insn))->insn (0);
-
-  if (NONJUMP_INSN_P (stop_insn)
-  && GET_CODE (PATTERN (stop_insn)) == SEQUENCE)
-stop_insn = next_insn (PREV_INSN (stop_insn));
-
-  for (insn = start_insn; insn != stop_insn;
-   insn = next_insn_no_annul (insn))
+  /* If we found a basic block, get the live registers from it and update
+ them with anything set or killed between its start and the insn before
+ TARGET; this custom life analysis is really about registers so we need
+ to use the LR problem.  Otherwise, we must assume everything is live.  */
+  if (b != -1)
 {
-  rtx link;
-  rtx_insn *real_insn = insn;
-  enum rtx_code code = GET_CODE (insn);
-
-  if (DEBUG_INSN_P (insn))
-   continue;
-
-  /* If this insn is from the target of a branch, it isn't going to
-be used in the sequel.  If it is used in both cases, this
-test will not be true.  */
-  if ((code == INSN || code == JUMP_INSN || code == CALL_INSN)
- && INSN_FROM_TARGET_P (insn))
-   continue;
-
-  /* If this insn is a USE made by update_block, we care about the
-underlying insn.  */
-  if (code == INSN
- && GET_CODE (PATTERN (insn)) == USE
- && INSN_P (XEXP (PATTERN (insn), 0)))
-   real_insn = as_a  (XEXP (PATTERN (insn), 0));
-
-  if (CALL_P (real_insn))
+  regset regs_live = DF_LR_IN (BASIC_BLOCK_FOR_FN (cfun, b));
+  rtx_insn *start_insn, *stop_insn;
+  df_ref def;
+
+  /* Compute hard regs live at start of block.  */
+  REG_SET_TO_HARD_REG_SET (current_live_regs, regs_live);
+  FOR_EACH_ARTIFICIAL_DEF (def, b)
+   if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+ SET_HARD_REG_BIT (current_live_regs, DF_REF_REGNO (def));
+
+  /* Get starting and ending insn, handling the case where each might
+be a SEQUENCE.  */
+  start_insn = (b == ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->index ?
+   insns : BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, b)));
+  stop_insn = target;
+
+  if (NONJUMP_INSN_P (start_insn)
+ && GET_CODE (PATTERN (start_insn)) == SEQUENCE)
+   start_insn = as_a  (PATTERN (start_insn))->insn (0);
+
+  if (NONJUMP_INSN_P (stop_insn)
+ && GET_CODE (PATTERN (stop_insn)) == SEQUENCE)
+   stop_insn = next_insn (PREV_INSN (stop_insn));
+
+  for (insn = start_insn; insn != stop_insn;
+  insn = next_insn_no_annul (insn))
{
- /* Values in call-clobbered registers survive a COND_EXEC CALL
-if that is not executed; this matters for resoure use because
-they may be used by a complementarily (or more strictly)
-predicated instruction, or if the CALL is NORETURN.  */
- if (GET_CODE (PATTERN (real_insn)) != COND_EXEC)
+ rtx link;
+ rtx_insn *real_insn = insn;
+ enum rtx_code code = GET_CODE (insn);
+
+ if (DEBUG_INSN_P (insn))
+   continue;
+
+ /* If this insn is from the target of a branch, it isn't going to
+be used in the sequel.  If it is used in both cases, this
+test will not be true.  */
+ if ((code == INSN

[gcc r15-916] Revert "resource.cc: Replace calls to find_basic_block with cfgrtl BLOCK_FOR_INSN"

2024-05-29 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:c68bd7e8023f65d1dc23237f5a04a863344b1264

commit r15-916-gc68bd7e8023f65d1dc23237f5a04a863344b1264
Author: Hans-Peter Nilsson 
Date:   Thu May 30 01:57:39 2024 +0200

Revert "resource.cc: Replace calls to find_basic_block with cfgrtl 
BLOCK_FOR_INSN"

This reverts commit 933ab59c59bdc1ac9e3ca3a56527836564e1821b.

Diff:
---
 gcc/resource.cc | 66 -
 1 file changed, 56 insertions(+), 10 deletions(-)

diff --git a/gcc/resource.cc b/gcc/resource.cc
index 0d8cde93570..06fcfd3e44c 100644
--- a/gcc/resource.cc
+++ b/gcc/resource.cc
@@ -28,7 +28,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm_p.h"
 #include "regs.h"
 #include "emit-rtl.h"
-#include "cfgrtl.h"
 #include "resource.h"
 #include "insn-attr.h"
 #include "function-abi.h"
@@ -76,6 +75,7 @@ static HARD_REG_SET current_live_regs;
 static HARD_REG_SET pending_dead_regs;
 
 static void update_live_status (rtx, const_rtx, void *);
+static int find_basic_block (rtx_insn *, int);
 static rtx_insn *next_insn_no_annul (rtx_insn *);
 
 /* Utility function called from mark_target_live_regs via note_stores.
@@ -113,6 +113,46 @@ update_live_status (rtx dest, const_rtx x, void *data 
ATTRIBUTE_UNUSED)
CLEAR_HARD_REG_BIT (pending_dead_regs, i);
   }
 }
+
+/* Find the number of the basic block with correct live register
+   information that starts closest to INSN.  Return -1 if we couldn't
+   find such a basic block or the beginning is more than
+   SEARCH_LIMIT instructions before INSN.  Use SEARCH_LIMIT = -1 for
+   an unlimited search.
+
+   The delay slot filling code destroys the control-flow graph so,
+   instead of finding the basic block containing INSN, we search
+   backwards toward a BARRIER where the live register information is
+   correct.  */
+
+static int
+find_basic_block (rtx_insn *insn, int search_limit)
+{
+  /* Scan backwards to the previous BARRIER.  Then see if we can find a
+ label that starts a basic block.  Return the basic block number.  */
+  for (insn = prev_nonnote_insn (insn);
+   insn && !BARRIER_P (insn) && search_limit != 0;
+   insn = prev_nonnote_insn (insn), --search_limit)
+;
+
+  /* The closest BARRIER is too far away.  */
+  if (search_limit == 0)
+return -1;
+
+  /* The start of the function.  */
+  else if (insn == 0)
+return ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->index;
+
+  /* See if any of the upcoming CODE_LABELs start a basic block.  If we reach
+ anything other than a CODE_LABEL or note, we can't find this code.  */
+  for (insn = next_nonnote_insn (insn);
+   insn && LABEL_P (insn);
+   insn = next_nonnote_insn (insn))
+if (BLOCK_FOR_INSN (insn))
+  return BLOCK_FOR_INSN (insn)->index;
+
+  return -1;
+}
 
 /* Similar to next_insn, but ignores insns in the delay slots of
an annulled branch.  */
@@ -674,8 +714,7 @@ mark_target_live_regs (rtx_insn *insns, rtx 
target_maybe_return, struct resource
 }
 
   if (b == -1)
-b = BLOCK_FOR_INSN (target)->index;
-  gcc_assert (b != -1);
+b = find_basic_block (target, param_max_delay_slot_live_search);
 
   if (target_hash_table != NULL)
 {
@@ -683,7 +722,7 @@ mark_target_live_regs (rtx_insn *insns, rtx 
target_maybe_return, struct resource
{
  /* If the information is up-to-date, use it.  Otherwise, we will
 update it below.  */
- if (b == tinfo->block && tinfo->bb_tick == bb_ticks[b])
+ if (b == tinfo->block && b != -1 && tinfo->bb_tick == bb_ticks[b])
{
  res->regs = tinfo->live_regs;
  return;
@@ -866,6 +905,7 @@ void
 init_resource_info (rtx_insn *epilogue_insn)
 {
   int i;
+  basic_block bb;
 
   /* Indicate what resources are required to be valid at the end of the current
  function.  The condition code never is and memory always is.
@@ -935,8 +975,10 @@ init_resource_info (rtx_insn *epilogue_insn)
   target_hash_table = XCNEWVEC (struct target_info *, TARGET_HASH_PRIME);
   bb_ticks = XCNEWVEC (int, last_basic_block_for_fn (cfun));
 
-  /* Set the BLOCK_FOR_INSN for each insn.  */
-  compute_bb_for_insn ();
+  /* Set the BLOCK_FOR_INSN of each label that starts a basic block.  */
+  FOR_EACH_BB_FN (bb, cfun)
+if (LABEL_P (BB_HEAD (bb)))
+  BLOCK_FOR_INSN (BB_HEAD (bb)) = bb;
 }
 
 /* Free up the resources allocated to mark_target_live_regs ().  This
@@ -945,6 +987,8 @@ init_resource_info (rtx_insn *epilogue_insn)
 void
 free_resource_info (void)
 {
+  basic_block bb;
+
   if (target_hash_table != NULL)
 {
   int i;
@@ -971,7 +1015,9 @@ free_resource_info (void)
   bb_ticks = NULL;
 }
 
-  free_bb_for_insn ();
+  FOR_EACH_BB_FN (bb, cfun)
+if (LABEL_P (BB_HEAD (bb)))
+  BLOCK_FOR_INSN (BB_HEAD (bb)) = NULL;
 }
 
 /* Clear any hashed information that we have stored for INSN.  */
@@ -1017,10 +1063,10 @@ clear_hashed_info_until_next_barrier (rtx_insn *insn)
 void
 incr_ticks

[gcc r15-3699] testsuite/gcc.dg/pr84877.c: Add machinery to stabilize stack aligmnent

2024-09-18 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:b1ea710b1bcdda233f96538c5404228d2b244e01

commit r15-3699-gb1ea710b1bcdda233f96538c5404228d2b244e01
Author: Hans-Peter Nilsson 
Date:   Thu Sep 5 17:02:23 2024 +0200

testsuite/gcc.dg/pr84877.c: Add machinery to stabilize stack aligmnent

This test awkwardly "blinks"; xfails and xpasses apparently
randomly for cris-elf using the "gdb simulator".  On
inspection, I see that the stack address depends on the
number of environment variables, deliberately passed to the
simulator, each adding the size of a pointer.

This test is IMHO important enough not to be just skipped
just because it blinks (fixing the actual problem is a
different task).

I guess a random non-16 stack-alignment could happen for
other targets as well, so let's try and add a generic
machinery to "stabilize" the test as failing, by allocating
a dynamic amount to make sure it's misaligned.  The most
target-dependent item here is an offset between the incoming
stack-pointer value (within main in the added framework) and
outgoing (within "xmain" as called from main when setting up
the p0 parameter).  I know there are other wonderful stack
shapes, but such targets would fall under the "complicated
situations"-label and are no worse off than before.

* gcc.dg/pr84877.c: Try to make the test result consistent by
misaligning the stack.

Diff:
---
 gcc/testsuite/gcc.dg/pr84877.c | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/pr84877.c b/gcc/testsuite/gcc.dg/pr84877.c
index e82991f42dd4..2f2e29578df9 100644
--- a/gcc/testsuite/gcc.dg/pr84877.c
+++ b/gcc/testsuite/gcc.dg/pr84877.c
@@ -3,6 +3,32 @@
 
 #include 
 
+#ifdef __CRIS__
+#define OUTGOING_SP_OFFSET (-sizeof (void *))
+/* Suggestion: append #elif defined() after this 
comment,
+   either defining OUTGOING_SP_OFFSET to whatever the pertinent amount is at 
-O2,
+   if that makes your target consistently fail this test, or define
+   DO_NOT_TAMPER for more complicated situations.  Either way, compile with
+   -DDO_NO_TAMPER to avoid any meddling.  */
+#endif
+
+#if defined (OUTGOING_SP_OFFSET) && !defined (DO_NOT_TAMPER)
+extern int xmain () __attribute__ ((__noipa__));
+int main ()
+{
+  uintptr_t misalignment
+= (OUTGOING_SP_OFFSET
++ (15 & (uintptr_t) __builtin_stack_address ()));
+  /* Allocate a minimal amount if the stack was accidentally aligned.  */
+  void *q = __builtin_alloca (misalignment == 0);
+  xmain ();
+  /* Fake use to avoid the "allocation" being optimized out.  */
+  asm volatile ("" : : "rm" (q));
+  return 0;
+}
+#define main xmain
+#endif
+
 struct U {
 int M0;
 int M1;


[gcc r15-3782] testsuite/gfortran.dg/unsigned_22.f90: Add missing close with delete, PR116701

2024-09-22 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:3f37c6f47cd50c99350e93ef0dab31f7dc6d213a

commit r15-3782-g3f37c6f47cd50c99350e93ef0dab31f7dc6d213a
Author: Hans-Peter Nilsson 
Date:   Mon Sep 23 03:29:02 2024 +0200

testsuite/gfortran.dg/unsigned_22.f90: Add missing close with delete, 
PR116701

Without this patch, gfortran.dg/unsigned_22.f90 fails for
non-effective-target fd_truncate targets, i.e. targets that
don't support chsize or ftruncate.  See also
libgfortran/io/unix.c:raw_truncate.  It passes on the first
run, but leaves behind a file "fort.10" which is then picked
up by subsequent runs, but since that file is to be
rewritten, the libgfortran machinery tries to truncate it,
which fails.  The file always being left behind, is
primarily because the test-case lacks a deleting
close-statement, apparently accidentally.

Incidentally, this "fort.10" artefact is also picked up by
gfortran.dg/write_check3.f90 causing that test to fail too,
observable as a regression for non-fd_truncate targets since
the unsigned_22.f90 introduction.  Also, when running
e.g. the whole of gfortran.dg/dg.exp, the "fort.10" is later
deleted by gfortran.dg/write_direct_eor.f90 (which
regardlessly passes), erasing the clue of the cause of the
write_check3 failure.  Also, running just
dg.exp=write_check3.f90 or manually repeating the commands
in gfortran.log showed no error.

N.B.: this close-statement will not help if unsigned_22 for
some reason fails, executing one of the "stop" statements,
but that's also the case for many other tests.

PR testsuite/116701
* gfortran.dg/unsigned_22.f90: Add missing close with delete.

Diff:
---
 gcc/testsuite/gfortran.dg/unsigned_22.f90 | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gfortran.dg/unsigned_22.f90 
b/gcc/testsuite/gfortran.dg/unsigned_22.f90
index bc2f810238de..2a8434ccb6ec 100644
--- a/gcc/testsuite/gfortran.dg/unsigned_22.f90
+++ b/gcc/testsuite/gfortran.dg/unsigned_22.f90
@@ -22,4 +22,5 @@ program memain
   read (10,*,iostat=iostat,iomsg=iomsg) u
   if (iostat == 0) error stop 7
   if (iomsg /= "Unsigned integer overflow while reading item 1 of list input") 
error stop 8
+  close(unit=10, status='delete')
  end program memain


[gcc r15-3880] gfortran testsuite: Remove unit-files in files having open-statements, PR116701

2024-09-25 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:14cd10815a39cc131662d4b6759ff6712ddd0b6d

commit r15-3880-g14cd10815a39cc131662d4b6759ff6712ddd0b6d
Author: Hans-Peter Nilsson 
Date:   Mon Sep 23 18:44:11 2024 +0200

gfortran testsuite: Remove unit-files in files having open-statements, 
PR116701

PR testsuite/116701 shows that left-behind files from
unnamed gfortran open statements (named unit.N, where N =
unit number) can interfere with the result of a subsequent
run.  While that's unlikely to happen for a "real" fortran
target or a test with a deleting close-statement, test-cases
should not rely on previous test-cases passing and not
execute along different execution paths depending on earlier
runs, even if the difference is benevolent.

Most but not all fortran test-cases go through
gfortran-dg-runtest (gfortran.dg) or fortran-torture-execute
(gfortran.fortran-torture).  However, the exceptions, with
more complex framework and call-chains, either don't run or
don't have open-statements, so a more complex solution
doesn't seem worthwhile.  If test-cases with open-statements
are added later to those parts of the test-suite, calls to
fortran-delete-unit-files at the right spot may be added or
worst case, "manual" cleanup-calls added, like:
! { dg-final { remote_file target delete "fort.10" } }
Put the new proc in fortran-modules.exp since that's where other
common fortran-testsuite dejagnu-library functions are located.

PR testsuite/116701
* lib/fortran-modules.exp (fortran-delete-unit-files): New proc.
* lib/gfortran-dg.exp (gfortran-dg-runtest): Call
fortran-delete-unit-files after executing test.
* lib/fortran-torture.exp (fortran-torture-execute): Ditto.

Diff:
---
 gcc/testsuite/lib/fortran-modules.exp | 21 +
 gcc/testsuite/lib/fortran-torture.exp |  2 ++
 gcc/testsuite/lib/gfortran-dg.exp |  1 +
 3 files changed, 24 insertions(+)

diff --git a/gcc/testsuite/lib/fortran-modules.exp 
b/gcc/testsuite/lib/fortran-modules.exp
index 158b16bada91..a7196f13ed22 100644
--- a/gcc/testsuite/lib/fortran-modules.exp
+++ b/gcc/testsuite/lib/fortran-modules.exp
@@ -172,3 +172,24 @@ proc igrep { args } {
 }
 return $grep_out
 }
+
+# If the code has any "open" statements for numbered units, make sure
+# no corresponding output file remains.  Redundant remove operations
+# are ok, but duplicate removals look sloppy, so track for uniqueness.
+proc fortran-delete-unit-files { src } {  
+set openpat {open *\( *(?:unit *= *)?([0-9]+)}
+set openmatches [igrep $src $openpat]
+if {![string match "" $openmatches]} {
+   # verbose -log "Found \"$openmatches\""
+   set deleted_units {}
+   foreach openmatch $openmatches {
+   regexp -nocase -- "$openpat" $openmatch match unit
+   if {[lsearch $deleted_units $unit] < 0} {
+   set rmfile "fort.$unit"
+   verbose -log "Deleting $rmfile"
+   remote_file target delete "fort.$unit"
+   lappend deleted_units $unit
+   }
+   }
+}
+}
diff --git a/gcc/testsuite/lib/fortran-torture.exp 
b/gcc/testsuite/lib/fortran-torture.exp
index 66f5bc822232..0727fb4fb0a6 100644
--- a/gcc/testsuite/lib/fortran-torture.exp
+++ b/gcc/testsuite/lib/fortran-torture.exp
@@ -332,6 +332,8 @@ proc fortran-torture-execute { src } {
catch { remote_file build delete $executable }
 }
$status "$testcase execution, $option"
+
+   fortran-delete-unit-files $src
 }
 cleanup-modules ""
 }
diff --git a/gcc/testsuite/lib/gfortran-dg.exp 
b/gcc/testsuite/lib/gfortran-dg.exp
index fcba95dc3961..2edc09e5c995 100644
--- a/gcc/testsuite/lib/gfortran-dg.exp
+++ b/gcc/testsuite/lib/gfortran-dg.exp
@@ -160,6 +160,7 @@ proc gfortran-dg-runtest { testcases flags 
default-extra-flags } {
foreach flags_t $option_list {
verbose "Testing $nshort, $flags $flags_t" 1
dg-test $test "$flags $flags_t" ${default-extra-flags}
+   fortran-delete-unit-files $test
cleanup-modules ""
}
 }


[gcc r15-3909] testsuite/gfortran.dg/open_errors_2.f90: Remove now-redundant file deletion

2024-09-26 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:3471ae37200bd8154084334204a6f72a5bbae974

commit r15-3909-g3471ae37200bd8154084334204a6f72a5bbae974
Author: Hans-Peter Nilsson 
Date:   Thu Sep 26 23:07:01 2024 +0200

testsuite/gfortran.dg/open_errors_2.f90: Remove now-redundant file deletion

Now that fort.N files are removed by the testsuite
framework, remove this single "manual" file deletion.
(Also, it should have been "remote_file target delete",
since it's the target that creates the file, not the build
framework, which might matter to some setups.)

* gfortran.dg/open_errors_2.f90: Remove now-redundant file deletion.

Diff:
---
 gcc/testsuite/gfortran.dg/open_errors_2.f90 | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gcc/testsuite/gfortran.dg/open_errors_2.f90 
b/gcc/testsuite/gfortran.dg/open_errors_2.f90
index 72d63bb3a39f..dbe9112bc6fd 100644
--- a/gcc/testsuite/gfortran.dg/open_errors_2.f90
+++ b/gcc/testsuite/gfortran.dg/open_errors_2.f90
@@ -16,4 +16,3 @@
   rewind(522)
   close(522)
 end program
-! { dg-final { remote_file build delete "fort.345" } }


[gcc r15-3982] libstdc++-v3: Fix signed-overflow warning for newlib/ctype_base.h, PR116895

2024-09-30 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:b1696ffd46872907b324996d4cdf28a2b9df209d

commit r15-3982-gb1696ffd46872907b324996d4cdf28a2b9df209d
Author: Hans-Peter Nilsson 
Date:   Sun Sep 29 05:47:03 2024 +0200

libstdc++-v3: Fix signed-overflow warning for newlib/ctype_base.h, PR116895

There are 100+ regressions when running the g++ testsuite for newlib
targets (probably excepting ARM-based ones) e.g cris-elf after commit
r15-3859-g63a598deb0c9fc "libstdc++: #ifdef out #pragma GCC
system_header", which effectively no longer silences warnings for
gcc-installed system headers.  Some of these regressions are fixed by
r15-3928.  For the remaining ones, there's in g++.log:

FAIL: g++.old-deja/g++.robertl/eb79.C  -std=c++26 (test for excess errors)
Excess errors:
/gccobj/cris-elf/libstdc++-v3/include/cris-elf/bits/ctype_base.h:50:53: \
 warning: overflow in conversion from 'int' to 'std::ctype_base::mask' \
 {aka 'char'} changes value from '151' to '-105' [-Woverflow]

This is because the _B macro in newlib's ctype.h (from where the
"_" macros come) is bit 7, the sign-bit of 8-bit types:

#define _B  0200

Using it in an int-expression that is then truncated to 8 bits will
"change" the value to negative for a default-signed char.  If this
code was created from scratch, it should have been an unsigned type,
however it's not advisable to change the type of mask as this affects
the API.  The least ugly option seems to be to silence the warning by
explict casts in the initializer, and for consistency, doing it for
all members.

PR libstdc++/116895
* config/os/newlib/ctype_base.h: Avoid signed-overflow warnings by
explicitly casting initializer expressions to mask.

Diff:
---
 libstdc++-v3/config/os/newlib/ctype_base.h | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/libstdc++-v3/config/os/newlib/ctype_base.h 
b/libstdc++-v3/config/os/newlib/ctype_base.h
index 309fdeea7731..5ec43a0c6803 100644
--- a/libstdc++-v3/config/os/newlib/ctype_base.h
+++ b/libstdc++-v3/config/os/newlib/ctype_base.h
@@ -41,19 +41,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 // NB: Offsets into ctype::_M_table force a particular size
 // on the mask type. Because of this, we don't use an enum.
 typedef char   mask;
-static const mask upper= _U;
-static const mask lower= _L;
-static const mask alpha= _U | _L;
-static const mask digit= _N;
-static const mask xdigit   = _X | _N;
-static const mask space= _S;
-static const mask print= _P | _U | _L | _N | _B;
-static const mask graph= _P | _U | _L | _N;
-static const mask cntrl= _C;
-static const mask punct= _P;
-static const mask alnum= _U | _L | _N;
+static const mask upper= mask (_U);
+static const mask lower= mask (_L);
+static const mask alpha= mask (_U | _L);
+static const mask digit= mask (_N);
+static const mask xdigit   = mask (_X | _N);
+static const mask space= mask (_S);
+static const mask print= mask (_P | _U | _L | _N | _B);
+static const mask graph= mask (_P | _U | _L | _N);
+static const mask cntrl= mask (_C);
+static const mask punct= mask (_P);
+static const mask alnum= mask (_U | _L | _N);
 #if __cplusplus >= 201103L
-static const mask blank= space;
+static const mask blank= mask (space);
 #endif
   };


[gcc r15-6554] MMIX: Replace format for private symbol output by output-time adjustment

2025-01-03 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:8395cf72b49f1418deccc92c50accd2464177a45

commit r15-6554-g8395cf72b49f1418deccc92c50accd2464177a45
Author: Hans-Peter Nilsson 
Date:   Fri Jan 3 18:25:36 2025 +0100

MMIX: Replace format for private symbol output by output-time adjustment

All this started with belated MMIX regression patrol in observance of
the holidays, looking at gcc.dg/Wstringop-overflow-27.c as a
regression for target mmix.  That's because of a single message not
matched, where there is "note: destination object 'vla::22'" instead
of the expected "note: destination object 'vla'" due to
r11-5523-geafe8ee7af13c3 in which the message format and the match
changed.

That ::22 is because some identifiers that are SSA_NAME-versions and
other clones are "privatized" by ASM_FORMAT_PRIVATE_NAME and its
companion macro by default, ASM_PN_FORMAT; see the patch.  I found
that these "private names" were "unprivatized" for the purpose of
warnings and error messages *in code that only handles the default
format*, "%s.%lu".

I went ahead and wrote and tested a patch-set to hookize that
unprivatizing code, but found that it would only affect errors and
warnings; dumps still had the "target format".  While having bad
thoughts about being hit by yet another structural testism because of
the choice of outputting yet another target-specific format instead of
a canonical "versioned" format, I realized it *already was handling a
canonical format*: only the default "%s.%lu" is properly handled.

To wit, targets are better off with the default "%s.%lu" and adjusting
it (if needed, including not allowing "." or "$"), *at time of
assembly code output*.  IOW, outputs, both references and definitions,
pass a single label-output target code point: ASM_OUTPUT_LABELREF,
which is that time of output.  Some older testsuite adjustments need
to be unadjusted, but is another rabbit-hole, so I've kept that change
separate.  Other tests checking dumps, now started to pass for the
first time, some 20+.

* config/mmix/mmix.cc (mmix_asm_output_labelref): Replace '.'
with '::'.
* config/mmix/mmix.h (ASM_PN_FORMAT): Define to actual default.

Diff:
---
 gcc/config/mmix/mmix.cc | 29 +
 gcc/config/mmix/mmix.h  | 10 +-
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/gcc/config/mmix/mmix.cc b/gcc/config/mmix/mmix.cc
index 13b6c39c7678..e167ffcb6609 100644
--- a/gcc/config/mmix/mmix.cc
+++ b/gcc/config/mmix/mmix.cc
@@ -1586,6 +1586,35 @@ mmix_asm_output_labelref (FILE *stream, const char *name)
 if (*name == '@')
   is_extern = 0;
 
+  size_t ndots = 0;
+  for (const char *s = name; *s != 0; s++)
+if (*s == '.')
+  ndots++;
+
+  /* Replace all '.' with '::'.  We don't want a '.' as part of an identifier
+ as that'd be incompatible with mmixal.  We also don't want to do things
+ like overriding the default "%s.%lu" by '#define ASM_PN_FORMAT "%s::%lu"'
+ as that format will show up in warnings and error messages.  The default
+ won't show up in warnings and errors, as there are mechanisms in place to
+ strip that (but that only handles the default format).  FIXME: Make sure
+ no ":" is seen in the object file; we don't really want that mmixal
+ feature visible there.  */
+  if (ndots > 0)
+{
+  char *colonized_name = XALLOCAVEC (char, strlen (name) + 1 + ndots);
+
+  char *cs = colonized_name;
+  const char *s = name;
+  for (; *s != 0; s++)
+   {
+ if (*s == '.')
+   *cs++ = ':';
+ *cs++ = *s;
+   }
+  *cs = 0;
+  name = colonized_name;
+}
+
   asm_fprintf (stream, "%s%U%s",
   is_extern && TARGET_TOPLEVEL_SYMBOLS ? ":" : "",
   name);
diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h
index 47db27594d7a..44669e195b4a 100644
--- a/gcc/config/mmix/mmix.h
+++ b/gcc/config/mmix/mmix.h
@@ -656,11 +656,11 @@ typedef struct { int regs; int lib; } CUMULATIVE_ARGS;
 #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
  sprintf (LABEL, "*%s:%ld", PREFIX, (long)(NUM))
 
-/* Insert "::"; these are rarer than internal labels.  FIXME: Make sure no
-   ":" is seen in the object file; we don't really want that mmixal
-   feature visible there.  We don't want the default, which uses a dot;
-   that'd be incompatible with mmixal.  */
-#define ASM_PN_FORMAT "%s::%lu"
+/* Override the default, which looks at NO_DOT_IN_LABEL and NO_DOLLAR_IN_LABEL.
+   We want the real default "%s.%lu" in dumps and compiler messages, but the
+   actual assembly code format is adjusted to the effect of "%s::%lu".  See
+   mmix_asm_output_labelref.  */
+#define ASM_PN_FORMAT "%s.%lu"
 
 #define ASM_OUTPUT_DEF(STREAM, NAME, VALUE) \
  mmix_asm_output_def (STREAM, NAME, VALUE)


[gcc r15-6555] testsuite: Replace MMIX-specific adjustments with TARGET_CALLEE_COPIES-adjustments

2025-01-03 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:ea228f22be816023def6cdb48e9f10a60f370833

commit r15-6555-gea228f22be816023def6cdb48e9f10a60f370833
Author: Hans-Peter Nilsson 
Date:   Fri Jan 3 18:34:14 2025 +0100

testsuite: Replace MMIX-specific adjustments with 
TARGET_CALLEE_COPIES-adjustments

With the dump now emitting "privatized symbols" in the default
"%s.%lu" format also for MMIX, there's still a difference for MMIX.
This time it's because numbers have changed (copies introduced before
this point) because it has TARGET_CALLEE_COPIES yielding true.
Redundant copies may have been elided at this point, but the change
in name remains.

Since that's true for other targets too, an obvious change is to
generalize the tested patterns to include TARGET_CALLEE_COPIES-true
targets, as a brief inspection of the history of these tests shows
that the point of these tests lie not in whether copies have been done
but in the part of the pattern that match a constant.

Also fixed up a "." where there should have been a "\\.".

* gcc.dg/tree-ssa/vector-4.c: Replace MMIX adjustments with
TARGET_CALLEE_COPIES-agnostic adjustments.
* gcc.dg/tree-ssa/forwprop-36.c: Ditto.  Correct pattern to match a
literal ".".

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/forwprop-36.c | 3 +--
 gcc/testsuite/gcc.dg/tree-ssa/vector-4.c| 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-36.c 
b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-36.c
index f3871bf45e86..d00b957a7d67 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-36.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-36.c
@@ -21,5 +21,4 @@ main ()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump "if \\(b.0_\[0-9\]+ != 0\\)" "cddce1" { target 
{ ! mmix-knuth-mmixware } } } } */
-/* { dg-final { scan-tree-dump "if \\(b::1_\[0-9\]+ != 0\\)" "cddce1" { target 
{ mmix-knuth-mmixware } } } } */
+/* { dg-final { scan-tree-dump "if \\(b\\.\[01\]_\[0-9\]+ != 0\\)" "cddce1" } 
} */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vector-4.c 
b/gcc/testsuite/gcc.dg/tree-ssa/vector-4.c
index 982a2a47d6a0..03d70fde55a8 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vector-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vector-4.c
@@ -10,6 +10,5 @@ v4si vs (v4si a, v4si b)
 }
 
 /* The compound literal should be placed directly in the vec_perm.  */
-/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR ;" 1 
"gimple" { target { ! mmix-knuth-mmixware } } } } */
-/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR ;" 1 "gimple" { target mmix-knuth-mmixware } } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR ;" 1 "gimple" } } */


[gcc r15-6456] libstdc++-v3/testsuite/.../year_month_day/3.cc, 4.cc: Cut down for simulators

2024-12-28 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:4da027d87eabd9a6cb0f5c1ed7ee10540501c7a3

commit r15-6456-g4da027d87eabd9a6cb0f5c1ed7ee10540501c7a3
Author: Hans-Peter Nilsson 
Date:   Sun Dec 29 03:32:04 2024 +0100

libstdc++-v3/testsuite/.../year_month_day/3.cc, 4.cc: Cut down for 
simulators

These two long-running tests happened to fail for me when
run in parallel (nprocs - 1) compared to a serial run, for
target mmix on my laptop.  The runtime is 3m40s for 3.cc
before this change, and 0.9s afterwards.

* testsuite/std/time/year_month_day/3.cc (test01): Add ifdeffery to
limit the tested dates.  For simulators, pass start and end dates
limiting the tested range to 10 days, centered on days (0).
* testsuite/std/time/year_month_day/4.cc: Ditto.

Diff:
---
 libstdc++-v3/testsuite/std/time/year_month_day/3.cc | 11 ++-
 libstdc++-v3/testsuite/std/time/year_month_day/4.cc | 10 +-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/testsuite/std/time/year_month_day/3.cc 
b/libstdc++-v3/testsuite/std/time/year_month_day/3.cc
index 05dc750c0a09..f4829a686f79 100644
--- a/libstdc++-v3/testsuite/std/time/year_month_day/3.cc
+++ b/libstdc++-v3/testsuite/std/time/year_month_day/3.cc
@@ -1,4 +1,5 @@
 // { dg-do run { target c++20 } }
+// { dg-additional-options "-DSTART_DAY=-5 -DEND_DAY=5 
-DSTART_YMD=1833y/February/8d" { target simulator } }
 
 // Copyright (C) 2021-2024 Free Software Foundation, Inc.
 //
@@ -50,11 +51,19 @@ void test01()
 {
   using namespace std::chrono;
 
+#ifdef START_DAY
+  auto n   = days{START_DAY};
+  auto ymd = START_YMD;
+  auto end_day = days{END_DAY};
+#else
   // [-12687428, 11248737] maps to [-32767y/January/1d, 32767y/December/31d]
 
   auto n   = days{-12687428};
   auto ymd = -32767y/January/1d;
-  while (n < days{11248737}) {
+  auto end_day = days{11248737};
+#endif
+
+  while (n < end_day) {
 VERIFY( year_month_day{sys_days{n}} == ymd );
 ++n;
 advance(ymd);
diff --git a/libstdc++-v3/testsuite/std/time/year_month_day/4.cc 
b/libstdc++-v3/testsuite/std/time/year_month_day/4.cc
index 6b6714e3a85e..09a7551dcfc0 100644
--- a/libstdc++-v3/testsuite/std/time/year_month_day/4.cc
+++ b/libstdc++-v3/testsuite/std/time/year_month_day/4.cc
@@ -1,4 +1,5 @@
 // { dg-do run { target c++20 } }
+// { dg-additional-options "-DSTART_DAY=-5 -DSTART_YMD=1833y/February/8d 
-DEND_YMD=2106y/November/24d" { target simulator } }
 
 // Copyright (C) 2021-2024 Free Software Foundation, Inc.
 //
@@ -50,11 +51,18 @@ void test01()
 {
   using namespace std::chrono;
 
+#ifdef START_DAY
+  auto n   = days{START_DAY};
+  auto ymd = START_YMD;
+#else
   // [-32767y/January/1d, 32767y/December/31d] maps to [-12687428, 11248737]
 
   auto n   = days{-12687428};
   auto ymd = -32767y/January/1d;
-  while (ymd < 32767y/December/31d) {
+#define END_YMD 32767y/December/31d
+#endif
+
+  while (ymd < END_YMD) {
 VERIFY( static_cast(ymd) == sys_days{n} );
 ++n;
 advance(ymd);


[gcc r15-6463] MMIX: Correct handling of C23 (...) functions, PR117618

2024-12-29 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:8a4e57e6bc63eba78e5f3b0090e58d48a95dcbc7

commit r15-6463-g8a4e57e6bc63eba78e5f3b0090e58d48a95dcbc7
Author: Hans-Peter Nilsson 
Date:   Sun Dec 29 08:14:14 2024 +0100

MMIX: Correct handling of C23 (...) functions, PR117618

This commit fixes a MMIX C23 (...)-handling bug; failing
gcc.dg/c23-stdarg-[46789].c execution tests.   But, this
isn't about a missing "|| arg.type != NULL_TREE" in the
PORT_setup_incoming_varargs function like most other
PR114175 port bugs exposed by the gcc.dg/c23-stdarg-6.c
.. -9.c tests; the MMIX port passes struct-return-values in
a register.  But, the bug is somewhat similar.

This bug seems like it was added already in
r13-3549-g4fe34cdcc80ac2, by incorrectly handling
TYPE_NO_NAMED_ARGS_STDARG_P-functions ((...)-functions);
counting them as having one parameter instead of none.  That
"+ 1" below is a kind-of hidden function_arg_advance call,
which shouldn't happen for (...)-functions.

PR target/117618
* config/mmix/mmix.cc (mmix_setup_incoming_varargs):
Correct handling of C23 (...)-functions.

Diff:
---
 gcc/config/mmix/mmix.cc | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/gcc/config/mmix/mmix.cc b/gcc/config/mmix/mmix.cc
index ce014387e614..39725c96991b 100644
--- a/gcc/config/mmix/mmix.cc
+++ b/gcc/config/mmix/mmix.cc
@@ -990,10 +990,18 @@ mmix_setup_incoming_varargs (cumulative_args_t 
args_so_farp_v,
 {
   CUMULATIVE_ARGS *args_so_farp = get_cumulative_args (args_so_farp_v);
 
-  /* The last named variable has been handled, but
- args_so_farp has not been advanced for it.  */
-  if (args_so_farp->regs + 1 < MMIX_MAX_ARGS_IN_REGS)
-*pretend_sizep = (MMIX_MAX_ARGS_IN_REGS - (args_so_farp->regs + 1)) * 8;
+  /* Better pay special attention to (...) functions and not fold that
+ case into the general case in the else-arm.  */
+  if (TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+{
+  *pretend_sizep = MMIX_MAX_ARGS_IN_REGS * 8;
+  gcc_assert (args_so_farp->regs == 0);
+}
+  else
+/* The last named variable has been handled, but
+   args_so_farp has not been advanced for it.  */
+if (args_so_farp->regs + 1 < MMIX_MAX_ARGS_IN_REGS)
+  *pretend_sizep = (MMIX_MAX_ARGS_IN_REGS - (args_so_farp->regs + 1)) * 8;
 
   /* We assume that one argument takes up one register here.  That should
  be true until we start messing with multi-reg parameters.  */


[gcc r15-6071] testsuite/gcc.dg/tree-ssa/pr111456-1.c: Handle fallout

2024-12-09 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:0374e6771477553b3cc0c13f000f9e79aabd5020

commit r15-6071-g0374e6771477553b3cc0c13f000f9e79aabd5020
Author: Hans-Peter Nilsson 
Date:   Sun Dec 8 19:40:55 2024 +0100

testsuite/gcc.dg/tree-ssa/pr111456-1.c: Handle fallout

This is expected fallout from r15-5646-gd1cf0d7a0f27fd as
described by that commit.  The =0 case is covered by
PR117973.

PR tree-optimization/117954
* gcc.dg/tree-ssa/pr111456-1.c: Pass
--param=logical-op-non-short-circuit=1.

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/pr111456-1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr111456-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr111456-1.c
index 664a1afa..2e89228761c7 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr111456-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr111456-1.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-optimized --param 
logical-op-non-short-circuit=1" } */
 /* PR tree-optimization/111456 */
 
 void foo(void);


[gcc r15-6081] testsuite/gcc.dg/tree-ssa/pr117973-1.c: New test

2024-12-10 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:0703e7491e06c09f2a37c9275d92dc32ae10015d

commit r15-6081-g0703e7491e06c09f2a37c9275d92dc32ae10015d
Author: Hans-Peter Nilsson 
Date:   Mon Dec 9 20:15:52 2024 +0100

testsuite/gcc.dg/tree-ssa/pr117973-1.c: New test

PR117973 covers the aspect of
non-LOGICAL_OP_NON_SHORT_CIRCUIT targets for PR111456, for
which the test-case gcc.dg/tree-ssa/pr111456-1.c started
failing as described in PR117954.

* gcc.dg/tree-ssa/pr117973-1.c: New test.

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/pr117973-1.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr117973-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr117973-1.c
new file mode 100644
index ..6523b3ce59fe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr117973-1.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized --param 
logical-op-non-short-circuit=0" } */
+/* PR tree-optimization/117973 */
+#include "pr111456-1.c"
+
+/* { dg-final { scan-tree-dump-not "foo " "optimized" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "return 0;" "optimized" } } */


[gcc r15-6287] testsuite: Force max-completely-peeled-insns=300 for CRIS, PR118055

2024-12-16 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:e5c84fd3c195eb5e553fde84e79dd83712edf732

commit r15-6287-ge5c84fd3c195eb5e553fde84e79dd83712edf732
Author: Hans-Peter Nilsson 
Date:   Mon Dec 16 18:47:03 2024 +0100

testsuite: Force max-completely-peeled-insns=300 for CRIS, PR118055

This handles fallout from r15-6097-gee2f19b0937b5e.  A brief
analysis shows that the metric used in that code is computed
by estimate_move_cost, differentiating on the target macro
MOVE_MAX_PIECES (which defaults to MOVE_MAX) which for most
"32-bit targets" is 4 and for "64-bit targets" is 8.  There
are some outliers, like pru, with MOVE_MAX set to 8 but
counting as a 32-bit target.

So, the main difference for this test-case, which is heavy
on 64-bit moves (most targets have "double" mapped to IEEE
64-bit), is between "32-bit" and "64-bit", with the cost up
to twice for the former compared to the latter.  I see no
effective_target_move_max_is_4 or equivalent, and this
instance falls below the threshold of adding one, so I'm
sticking to a list of targets.  For CRIS, it would suffice
with 210, but there's no need to be this specific, and it
would make the test even more brittle.

PR tree-optimization/118055
* gcc.dg/tree-ssa/pr83403-1.c, gcc.dg/tree-ssa/pr83403-2.c: Add
cris-*-* to targets passing --param=max-completely-peeled-insns=300.

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c | 2 +-
 gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c
index 293fd2dbd973..3cfda4f183cd 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-1.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O3 -funroll-loops -fdump-tree-lim2-details" } */
 /* { dg-additional-options "--param max-completely-peeled-insns=200" { target 
{ s390*-*-* } } } */
-/* { dg-additional-options "--param max-completely-peeled-insns=300" { target 
{ arm*-*-* } } } */
+/* { dg-additional-options "--param max-completely-peeled-insns=300" { target 
{ arm*-*-* cris-*-* } } } */
 
 #define TYPE unsigned int
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c
index b421b387bcab..00fa04ecb851 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83403-2.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O3 -funroll-loops -fdump-tree-lim2-details" } */
 /* { dg-additional-options "--param max-completely-peeled-insns=200" { target 
{ s390*-*-* } } } */
-/* { dg-additional-options "--param max-completely-peeled-insns=300" { target 
{ arm*-*-* } } } */
+/* { dg-additional-options "--param max-completely-peeled-insns=300" { target 
{ arm*-*-* cris-*-* } } } */
 
 #define TYPE int


[gcc r15-6827] c-pretty-print.cc (pp_c_tree_decl_identifier): Strip private name encoding, PR118303

2025-01-11 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:851e188c2abf935bb43a7e7ce2ac2e02c6a78ba8

commit r15-6827-g851e188c2abf935bb43a7e7ce2ac2e02c6a78ba8
Author: Hans-Peter Nilsson 
Date:   Mon Jan 6 08:44:04 2025 +0100

c-pretty-print.cc (pp_c_tree_decl_identifier): Strip private name encoding, 
PR118303

This is a part of PR118303.  It fixes
FAIL: gcc.dg/analyzer/CVE-2005-1689-minimal.c (test for excess errors)
FAIL: gcc.dg/analyzer/CVE-2005-1689-minimal.c inbuf.data (test for 
warnings, line 62)
for targets where the parameter on that line is subject to
TARGET_CALLEE_COPIES being true.

c-family:
PR middle-end/118303
* c-pretty-print.cc (c_pretty_printer::primary_expression) 
:
Call primary_expression for all SSA_NAME_VAR nodes and instead move 
the
DECL_ARTIFICIAL private name stripping to...
(pp_c_tree_decl_identifier): ...here.

Diff:
---
 gcc/c-family/c-pretty-print.cc | 39 +++
 1 file changed, 15 insertions(+), 24 deletions(-)

diff --git a/gcc/c-family/c-pretty-print.cc b/gcc/c-family/c-pretty-print.cc
index 22a71d1e3558..0b6810e12242 100644
--- a/gcc/c-family/c-pretty-print.cc
+++ b/gcc/c-family/c-pretty-print.cc
@@ -1398,29 +1398,7 @@ c_pretty_printer::primary_expression (tree e)
 
 case SSA_NAME:
   if (SSA_NAME_VAR (e))
-   {
- tree var = SSA_NAME_VAR (e);
- if (tree id = SSA_NAME_IDENTIFIER (e))
-   {
- const char *name = IDENTIFIER_POINTER (id);
- const char *dot;
- if (DECL_ARTIFICIAL (var) && (dot = strchr (name, '.')))
-   {
- /* Print the name without the . suffix (such as in VLAs).
-Use pp_c_identifier so that it can be converted into
-the appropriate encoding.  */
- size_t size = dot - name;
- char *ident = XALLOCAVEC (char, size + 1);
- memcpy (ident, name, size);
- ident[size] = '\0';
- pp_c_identifier (this, ident);
-   }
- else
-   primary_expression (var);
-   }
- else
-   primary_expression (var);
-   }
+   primary_expression (SSA_NAME_VAR (e));
   else if (gimple_assign_single_p (SSA_NAME_DEF_STMT (e)))
{
  /* Print only the right side of the GIMPLE assignment.  */
@@ -3033,7 +3011,20 @@ pp_c_tree_decl_identifier (c_pretty_printer *pp, tree t)
   gcc_assert (DECL_P (t));
 
   if (DECL_NAME (t))
-name = IDENTIFIER_POINTER (DECL_NAME (t));
+{
+  const char *dot;
+  name = IDENTIFIER_POINTER (DECL_NAME (t));
+  if (DECL_ARTIFICIAL (t) && (dot = strchr (name, '.')))
+   {
+ /* Print the name without the . suffix (such as in VLAs and
+callee-copied parameters).  */
+ size_t size = dot - name;
+ char *ident = XALLOCAVEC (char, size + 1);
+ memcpy (ident, name, size);
+ ident[size] = '\0';
+ name = ident;
+   }
+}
   else
 {
   static char xname[8];


[gcc r15-6429] testsuite/gcc.dg/memcmp-1.c: Cut down a factor of 7 for simulators

2024-12-23 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:11090da81e49c37fa5f271b0e0f10291eb0971bc

commit r15-6429-g11090da81e49c37fa5f271b0e0f10291eb0971bc
Author: Hans-Peter Nilsson 
Date:   Mon Dec 23 01:45:04 2024 +0100

testsuite/gcc.dg/memcmp-1.c: Cut down a factor of 7 for simulators

Running tests in parallel on my 4.5y+ old laptop made this
test time out: the test itself runs in 9m20s, the timeout
being 10 minutes with the 2x factor.  That's a bit too close.

This commit does to the base test a similar change as was
done for gcc.dg/torture/inline-mem-cpy-1.c in commit
r14-8188-g6eca0d23b7ea84; or IOW cut it down a factor of 7
(r14-8188 was by a factor of 11).

* gcc.dg/memcmp-1.c: Pass -DRUN_FRACTION=7 when testing in a 
simulator.

Diff:
---
 gcc/testsuite/gcc.dg/memcmp-1.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gcc.dg/memcmp-1.c b/gcc/testsuite/gcc.dg/memcmp-1.c
index 13ef5b3380d0..7a7832221560 100644
--- a/gcc/testsuite/gcc.dg/memcmp-1.c
+++ b/gcc/testsuite/gcc.dg/memcmp-1.c
@@ -2,6 +2,7 @@
 /* { dg-do run } */
 /* { dg-options "-O2" } */
 /* { dg-require-effective-target ptr32plus } */
+/* { dg-additional-options "-DRUN_FRACTION=7" { target simulator } } */
 /* { dg-timeout-factor 2 } */
 
 #include 


[gcc r15-6427] libgfortran: Fix build for targets with int32_t=long int

2024-12-23 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:a5b1f3e14ae6354bd7944dd5dd9c74880c7546db

commit r15-6427-ga5b1f3e14ae6354bd7944dd5dd9c74880c7546db
Author: Hans-Peter Nilsson 
Date:   Tue Dec 24 00:07:54 2024 +0100

libgfortran: Fix build for targets with int32_t=long int

Without this, after r15-6415-g586477d67bf2e3, you'll see,
for targets where int32_t is a typedef of long int (beware
of artificially broken lines):

/x/gcc/libgfortran/caf/single.c: In function '_gfortran_caf_get_by_ct':
/x/gcc/libgfortran/caf/single.c:2943:56: error: passing argument 2 of '\
(accessor_hash_table + (sizetype)((unsigned int)getter_index * 12))->ac\
cessor' from incompatible pointer type [-Wincompatible-pointer-types]
 2943 |   accessor_hash_table[getter_index].accessor (dst_ptr, &free_bu\
ffer, src_ptr,
  |^~~~\

  ||
  |int *
/x/gcc/libgfortran/caf/single.c:2943:56: note: expected 'int32_t *' {ak\
a 'long int *'} but argument is of type 'int *'

libgfortran:
* caf/single.c (_gfortran_caf_get_by_ct): Correct type of 
free_buffer
to int32_t.

Diff:
---
 libgfortran/caf/single.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libgfortran/caf/single.c b/libgfortran/caf/single.c
index f5414ff1f7ef..23ad44e1c162 100644
--- a/libgfortran/caf/single.c
+++ b/libgfortran/caf/single.c
@@ -2927,7 +2927,7 @@ _gfortran_caf_get_by_ct (
 {
   caf_single_token_t single_token = TOKEN (token);
   void *src_ptr = opt_src_desc ? (void *) opt_src_desc : single_token->memptr;
-  int free_buffer;
+  int32_t free_buffer;
   void *dst_ptr = opt_dst_desc ? (void *)opt_dst_desc : dst_data;
   void *old_dst_data_ptr = NULL;


[gcc r15-8676] libgfortran/intrinsics: Fix build for targets with int32_t=long int

2025-03-22 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:45d54c70ec54af88905397626f6912c512ab

commit r15-8676-g45d54c70ec54af88905397626f6912c512ab
Author: Hans-Peter Nilsson 
Date:   Sat Mar 22 18:27:10 2025 +0100

libgfortran/intrinsics: Fix build for targets with int32_t=long int

Without this, after r15-8650-g94fa9f4d27bac5, you'll see,
for targets where GFC_INTEGER_4 alias int32_t is a typedef
of long int (beware of artificially broken lines):

/x/gcc/libgfortran/intrinsics/reduce.c:269:1: error: conflicting types for 
'reduce_scalar_c'; have 'void(void *, index_type,  parray *, void (*)(void *, 
void *, void *), int *, gfc_array_l4 *, void *, void *, index_type,  
index_type)' {aka 'void(void *, long int,  parray *, void (*)(void *, void *, 
void *), int *, gfc_array_l4 *, void *, void *, long int,  long int)'}
  269 | reduce_scalar_c (void *res,
  | ^~~
[...] excessive error message verbiage deleted
/x/gcc/libgfortran/intrinsics/reduce.c: In function 'reduce_scalar_c':
/x/gcc/libgfortran/intrinsics/reduce.c:283:35: error: passing argument 4 of 
'reduce' from incompatible pointer type [-Wincompatible-pointer-types]
  283 |   reduce (&ret, array, operation, dim, mask, identity, ordered);
  |   ^~~
  |   |
  |   int *
/x/gcc/libgfortran/intrinsics/reduce.c:41:24: note: expected 'GFC_INTEGER_4 
*' {aka 'long int *'} but argument is of type 'int *'
   41 | GFC_INTEGER_4 *dim,
  | ~~~^~~
make[3]: *** [Makefile:4678: intrinsics/reduce.lo] Error 1

libgfortran:
* intrinsics/reduce.c (reduce_scalar_c): Correct type of parameter 
DIM.

Diff:
---
 libgfortran/intrinsics/reduce.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libgfortran/intrinsics/reduce.c b/libgfortran/intrinsics/reduce.c
index 63997d874baa..c8950e41fd01 100644
--- a/libgfortran/intrinsics/reduce.c
+++ b/libgfortran/intrinsics/reduce.c
@@ -270,7 +270,7 @@ reduce_scalar_c (void *res,
 index_type res_strlen __attribute__ ((unused)),
 parray *array,
 void (*operation) (void *, void *, void *),
-int *dim,
+GFC_INTEGER_4 *dim,
 gfc_array_l4 *mask,
 void *identity,
 void *ordered,


[gcc r15-9543] combine: Correct comments about combine_validate_cost

2025-04-16 Thread Hans-Peter Nilsson via Gcc-cvs
https://gcc.gnu.org/g:a4f81e168e02b0b1f8894070c6552b85672d4ee5

commit r15-9543-ga4f81e168e02b0b1f8894070c6552b85672d4ee5
Author: Hans-Peter Nilsson 
Date:   Tue Apr 15 06:08:36 2025 +0200

combine: Correct comments about combine_validate_cost

Fix misleading comments.  That function only determines whether
replacements cost more; it doesn't actually *validate* costs as being
cheaper.

For example, it returns true also if it for various reasons cannot
determine the costs, or if the new cost is the same, like when doing
an identity replacement.  The code has been the same since
r0-59417-g64b8935d4809f3.

* combine.cc: Correct comments about combine_validate_cost.

Diff:
---
 gcc/combine.cc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/combine.cc b/gcc/combine.cc
index 5f085187cfef..e1186087dff4 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -815,7 +815,7 @@ do_SUBST_LINK (struct insn_link **into, struct insn_link 
*newval)
 #define SUBST_LINK(oldval, newval) do_SUBST_LINK (&oldval, newval)
 
 /* Subroutine of try_combine.  Determine whether the replacement patterns
-   NEWPAT, NEWI2PAT and NEWOTHERPAT are cheaper according to insn_cost
+   NEWPAT, NEWI2PAT and NEWOTHERPAT are more expensive according to insn_cost
than the original sequence I0, I1, I2, I3 and undobuf.other_insn.  Note
that I0, I1 and/or NEWI2PAT may be NULL_RTX.  Similarly, NEWOTHERPAT and
undobuf.other_insn may also both be NULL_RTX.  Return false if the cost
@@ -4129,8 +4129,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, 
rtx_insn *i0,
}
 }
 
-  /* Only allow this combination if insn_cost reports that the
- replacement instructions are cheaper than the originals.  */
+  /* Reject this combination if insn_cost reports that the replacement
+ instructions are more expensive than the originals.  */
   if (!combine_validate_cost (i0, i1, i2, i3, newpat, newi2pat, other_pat))
 {
   undo_all ();