[gcc r15-311] Revert "Revert "testsuite/gcc.target/cris/pr93372-2.c: Handle xpass from combine improvement""
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
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
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"
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
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.
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
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
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
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"
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
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
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
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
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"
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"
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"
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 ();