Jakub Jelinek [Wed, 29 Jul 2026 21:34:54 +0000 (23:34 +0200)]
isel: Fix ICE on out of bounds vector elt access [PR126446]
The isel pass has a check for out of bounds constant index before
optimizing into .VEC_SET, but it does it using
// if index is a constant, then check the bounds
poly_uint64 idx_poly;
if (poly_int_tree_p (idx, &idx_poly))
{
poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (view_op0));
if (known_gt (idx_poly, nelts))
return false;
}
In the testcase below, idx is INTEGER_CST with long long type and
negative value, that doesn't fit into poly_uint64, so we happily convert
it into .VEC_SET.
Furthermore, the known_gt check looks wrong, already idx_poly known_eq
to nelts is too large and out of bounds for .VEC_SET.
This patch fixes that by punting if !poly_int_tree_p (idx, &idx_poly)
and poly_int_tree_p (idx), so when it is INTEGER_CST or POLY_INT_CST
which doesn't fit into poly_uint64 (so likely negative), and
uses known_ge instead of known_gt.
2026-07-29 Jakub Jelinek <jakub@redhat.com>
PR target/126446
* gimple-isel.cc (gimple_expand_vec_set_extract_expr): Punt if
idx doesn't fit into poly_uint64 but is poly_int_tree_p. Use
known_ge rather than known_gt for out of bounds check. Formatting
fixes.
James K. Lowden [Wed, 29 Jul 2026 18:00:41 +0000 (14:00 -0400)]
cobol: Accept newline in refmod pattern.
Modify lexer recognition of refmods and correct errors in is_refmod() function.
gcc/cobol/ChangeLog:
* parse.y: Report LPAREN token as '(', not ')'.
* scan.l: Remove newline exclusion from LPAREN pattern.
* scan_ante.h (rsearch): Helper function to ensure c++11 compatibility.
(trim_location): Use rsearch function.
(is_quote): New inline function to test quotiness.
(skip_string): New function to find end of string literal.
(is_refmod): Stay in bounds.
* util.cc (gcc_location_set): Decrease debug message verbosity.
Roger Sayle [Wed, 29 Jul 2026 16:39:42 +0000 (17:39 +0100)]
cris: PR rtl-optimization/126276: Restore build on cris-elf.
This patch resolves PR rtl-optimization/126276 which is a target-specific
regression on CRIS, triggered by a recent RTL simplification improvement.
The underlying problem is that cris.md's *cbranch<mode>4_btstrq1_<CC>
accepts more machines modes than the define_insn it is lowering to.
Fixed by adding the necessary modes to the *btst<mode> define_insn.
2026-07-29 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
PR target/126276
* config/cris/cris.md (*btst<BWD><ZnNNZSET): Handle BWD modes,
not just SImode.
(*cbranch<mode>4_btstrq1_<CC>): Likewise.
(*cbranch<mode>4_btstqb0_<CC>): Likewise.
Jonathan Wakely [Wed, 29 Jul 2026 15:55:39 +0000 (16:55 +0100)]
libstdc++: Fix grep for linker warning about --gc-sections [PR126452]
Current versions of GNU ld print "warning" with a lowercase 'w' so
adjust the grep patter. Also use LC_ALL=C to ensure the warning isn't
translated.
Because m4 uses square brackets as quotes, we need to use double
brackets in the grep pattern to expand to "[Ww]" in the configure
script.
libstdc++-v3/ChangeLog:
PR libstdc++/126452
* acinclude.m4 (GLIBCXX_CHECK_LINKER_FEATURES): Use LC_ALL_C and
match both "Warning" and "warning" in ld output.
* configure: Regenerate.
avoid-store-forwarding: Unshare load dest when re-applying extension [PR126434]
When store forwarding is avoided without eliminating the load (the store
only partially covers it), the extension wrapping the load's MEM is
re-applied after the bit-insert sequence, reusing SET_DEST (load) as the
move destination. As the load insn is kept here, that rtx is now shared
between two insns. That is fine for a plain REG, but in the case that the
dest is a SUBREG, it must not be shared (verify_rtx_sharing ICEs).
Unshare the destination with copy_rtx when building the move.
Bootstrapped/regtested on AArch64, x86-64 and PowerPC.
PR rtl-optimization/126434
gcc/ChangeLog:
* avoid-store-forwarding.cc (process_store_forwarding): Unshare the
load destination when building the re-extension move.
1. I forgot to negate the else value
2. one of the patterns was missing the mask.
This fixes it. The patterns moving the COND inwards are still useful because
they allow FMA forwarding as most micro-architectures don't forward FMA when
there's a random instruction like fneg in between.
Sorry for the mistakes. I added more tests to cover these now.
PR tree-optimization/126465
* gcc.target/aarch64/sve/cond_fma.c: New test.
* gcc.target/aarch64/sve/cond_fma_neg_addend.c: New test.
* gcc.target/aarch64/sve/cond_fms.c: New test.
* gcc.target/aarch64/sve/cond_fnma.c: New test.
* gcc.target/aarch64/sve/cond_fnms.c: New test.
Philipp Tomsich [Tue, 28 Jul 2026 13:28:33 +0000 (15:28 +0200)]
tree-optimization/126415 - perform inverse converted +- lookup in VN
The match.pd rewrite (T)a +- X -> (T)(a +- X') from r17-2078-g8395fa7c79eecf creates the narrow operation, assuming the
absence of overflow for an operation the program does not execute;
this results in wrong code (PR126415). Revert it and implement the
equivalence in visit_nary_op instead.
visit_nary_op value-numbers (T)(a +- b) <- (T)a +- (T)b. Add the
inverse, (T)a +- X <- (T)(a +- X'), looking up the narrow a +- X'
and converting the result. This makes the equivalence independent
of the order the two forms appear in the IL.
The transform is valid for sign changes and for widening conversions
from a type with undefined overflow when the narrow operation
dominates the statement being visited. The narrow operation is only
looked up, never created. X may be an integer constant that narrows
and extends back unchanged, or a conversion from the same narrow
type.
The sign-change case makes the fold apply to ilp32 targets as well;
remove the ilp32 xfail from the pr124545.c scan (PR116845).
Bootstrapped and regression-tested on x86_64-pc-linux-gnu.
* match.pd ((T)A +- CST -> (T)(A +- CST')): Revert.
* tree-ssa-sccvn.cc (ssa_integral_conversion_op): New function.
(vn_nary_result_avail_or_insertable_p): New function, split out
from ...
(visit_nary_op): ... here. Handle ((T)p) +- X by looking up
(p +- X') and converting the result, for X an integer constant
that narrows and extends back unchanged or a conversion from
the same narrow type.
gcc/testsuite/ChangeLog:
* gcc.dg/torture/pr126415.c: New testcase.
* gcc.dg/tree-ssa/ssa-fre-113.c: New testcase.
* gcc.dg/tree-ssa/ssa-fre-114.c: New testcase.
* gcc.dg/pr124545.c: Remove the ilp32 xfail.
Tomasz Kamiński [Tue, 28 Jul 2026 14:43:49 +0000 (16:43 +0200)]
libstdc++: Resolve UNTIL save adjustment at tzdb loading time [PR116110]
This patch moves the save calculation (ZoneInfo::calc_save) to database
loading code (reload_tzdb) instead of applying it on demand when zone
is queried (time_zone::_M_get_sys_info). This eliminates the performance
impact on non-first calls (that return the cached result), caused by
iterator adjustment checks.
Local performance test indicate a 10% cost (30ns to 33ns on average) for
cached queries with on-demand implementation (after r17-2466-g020e02fcf28),
combined with huge swings on time on first calls. This patch leads 200ms
increase (1.95s to 2.15s) on time of reload_tzdb, that happens only during
initial load (and later explicit reload).
As we need two bits of state (expanded or until_pending), I have decided
to keep the four value m_state enum.
PR libstdc++/116110
libstdc++-v3/ChangeLog:
* src/c++20/tzdb.cc (time_zone::_M_get_sys_info): Remove
ZoneInfo::calc_save invocation and related iterator adjustment.
(chrono::reload_tzdb): Calculate save (invoke calc_save) for
all infos on all zones.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
The following adds an early out for unsupported reduction operations
to avoid ICEing when the assumption that the GIMPLE stmt operand
number matches the SLP operand number breaks, as is for .CLZ with
two operands.
PR tree-optimization/126457
* tree-vect-loop.cc (vectorizable_reduction): Reject
operations where not all operands correspond to a SLP
child early.
Piotr Kubaj [Wed, 22 Jul 2026 13:45:04 +0000 (15:45 +0200)]
libgcc: rs6000: fix TOC restore when unwinding on FreeBSD powerpc64 ELFv2 [PR target/125803]
On powerpc64, when the unwind info for a frame does not explicitly
describe how r2 (the TOC pointer) was saved -- which is the normal case
for the linker-generated PLT call stubs -- frob_update_context inspects
the code stream to locate the saved TOC and arranges for r2 to be
restored from it.
The FreeBSD version of this hook hard-coded the ELFv1 TOC save slot
offset of 40 bytes, matching "std r2,40(r1)" (0xF8410028) and
"ld r2,40(r1)" (0xE8410028). FreeBSD/powerpc64 (both big-endian and
powerpc64le) uses ELFv2, where the TOC is saved at offset 24
("std r2,24(r1)" / "ld r2,24(r1)"). As a result the checks never
matched, r2 was left unrestored, and code reached by unwinding -- e.g. a
C++ catch handler in a different module than libgcc_s -- ran with the
wrong TOC. Any global or PLT access from such a handler then computed a
bogus address, typically crashing. This made C++ exceptions unusable on
FreeBSD/powerpc64le whenever gcc's shared libgcc_s provided the unwinder
(for instance any clang-built C++ program that pulls in libgfortran).
Define TOC_SAVE_SLOT based on _CALL_ELF (24 for ELFv2, 40 otherwise) and
use it throughout, and guard the ELFv1-only code-reading cases (the old
PLT stub form and the function pointer call sequence) with
_CALL_ELF != 2, mirroring linux-unwind.h.
libgcc/ChangeLog:
PR target/125803
* config/rs6000/freebsd-unwind.h (TOC_SAVE_SLOT): New macro,
defined according to _CALL_ELF.
(frob_update_context): Use TOC_SAVE_SLOT instead of the
hard-coded ELFv1 offset 40 when checking for and locating the
saved TOC, so that r2 is restored correctly under ELFv2. Guard
the ELFv1-only PLT stub and function pointer call sequences
with _CALL_ELF != 2, mirroring linux-unwind.h.
Thomas Schwinge [Mon, 27 Jul 2026 16:23:49 +0000 (18:23 +0200)]
OpenMP: Constructors and destructors for "declare target" static aggregates: Simplify offload tree dump scanning in test cases
The tests added in commit f1bfba3a9b3f31e3e06bfd1911c9f223869ea03f
'OpenMP: Constructors and destructors for "declare target" static aggregates'
carefully distinguish between AMD and NVIDIA GPU offloading compilations'
offload tree dump scanning -- but do exactly the same for both. (As expected.)
Therefore, no reason to duplicate these directives.
LoongArch: Adjust testcase for lasx-vec-construct-opt.c
Follow up to r17-2354-g10f6223d833, which changed the behavior of
vec_duplicate. The LoongArch architecture testcase need adjustments to
accommodate this change.
Jakub Jelinek [Wed, 29 Jul 2026 08:15:11 +0000 (10:15 +0200)]
i386: Fix ICE on out of bounds vector elt access [PR126446]
The following testcase ICEs on x86_64.
The isel pass has a check for out of bounds constant index before
optimizing into .VEC_SET, but it does it using
// if index is a constant, then check the bounds
poly_uint64 idx_poly;
if (poly_int_tree_p (idx, &idx_poly))
{
poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (view_op0));
if (known_gt (idx_poly, nelts))
return false;
}
In the testcase below, idx is INTEGER_CST with long long type and
negative value, that doesn't fit into poly_uint64, so we happily convert
it into .VEC_SET.
And another problem is that the x86 backend isn't trying to be careful
and handle out of bounds elt gracefully (I think it could still in theory
happen, if GIMPLE lets it through but e.g. something during expansion
figures out the index is constant or whatever).
The following patch fixes it in the backend to avoid triggering UB at compile
time by doing HOST_WIDE_INT_1U << elt etc. when elt is negative or too
large. In order to avoid ICE, we need to emit something, so I emit
a no-op move, out of bounds vector set shouldn't change anything in
the target.
gimple-isel.cc will be changed incrementally.
2026-07-29 Jakub Jelinek <jakub@redhat.com>
PR target/126446
* config/i386/i386-expand.cc (ix86_expand_vector_set): If elt is
out of bounds, emit a no-op move.
The following testcases ICE, because the build_bitint_stmt_ssa_conflicts
function sets for those ifns muldiv_p to true (similarly to the MULT_EXPR
and division/modulo ones) to prevent the lhs from being mapped into
the same underlying variable as the input operand(s).
Now, if the lhs and at least one of the operands
SSA_NAME_OCCURS_IN_ABNORMAL_PHI, we can trigger ICE because we fail to
coalesce something that has to be coalesced.
For MULT_EXPR etc. we handle this in gimple_lower_bitint, by
/* For multiplication and division with (ab)
lhs and one or both operands force the operands
into new SSA_NAMEs to avoid coalescing failures. */
if (TREE_CODE (rhs1) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
{
first_large_huge = 0;
tree t = make_ssa_name (TREE_TYPE (rhs1));
g = gimple_build_assign (t, SSA_NAME, rhs1);
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
gimple_set_location (g, loc);
gimple_assign_set_rhs1 (stmt, t);
if (rhs1 == rhs2)
{
gimple_assign_set_rhs2 (stmt, t);
rhs2 = t;
}
update_stmt (stmt);
}
etc. a few lines above the hunk below.
This patch just adds the same thing for the problematic internal
fn calls (not handling that way the .MUL_OVERFLOW etc. ifns,
because those do return COMPLEX_EXPR of BITINT_TYPE and so the
problematic case shouldn't exist there).
2026-07-29 Jakub Jelinek <jakub@redhat.com>
PR middle-end/126447
* gimple-lower-bitint.cc (gimple_lower_bitint): For
ifn calls with large/huge _BitInt (ab) SSA_NAME lhs if they
have such (ab) argument too, force it into temporary SSA_NAME
for IFN_BSWAP, IFN_BITREVERSE, IFN_UBSAN_CHECK_MUL and, if
bitint_big_endian, also for IFN_UBSAN_CHECK_{ADD,SUB}.
* gcc.dg/ubsan/bitint-5.c: New test.
* gcc.dg/bitint-138.c: New test.
Reviewed-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
testsuite/aarch64: update the fcmla counts in pr122408_1.f90
The test hard-codes two "fcmla ..., #0", which was the number trunk
happened to emit when it was added. BB SLP now also vectorises the two
plain-multiply subroutines: r17-141-g76b8869f08a6 ("tree-optimization/
124222 - rewrite BB SLP costing scalar coverage") taught
vect_bb_slp_scalar_cost to attribute the statements an SLP pattern node
covers, so the subgraph for c_add_ab and c_sub_ab is no longer costed as
unprofitable. They form .COMPLEX_MUL, and cmul<mode>3 expands each to
"fcmla #0" plus "fcmla #90", taking the #0 total from two to four.
For c_add_ab the loop body goes from a scalar pair of complex multiplies
i.e. ten instructions instead of fifteen, and the whole rotation mix
across the file changes from
#0=2 #90=0 #180=0 #270=2
to
#0=4 #90=2 #180=0 #270=2
The loop vectoriser is unchanged: its dumps are identical before and
after, the two conjugate subroutines still form .COMPLEX_MUL_CONJ, and
the #270 directive that actually tests PR122408 still passes. The
runtime companion pr122408_2.f90 also still runs clean.
Update the counts, and add a #90 count and a #180 scan-assembler-not.
PR122408 was about picking the wrong rotation pair after operand
swapping, so pinning the full rotation mix guards the regression more
directly than the #0 count did.
gcc/testsuite/ChangeLog:
* gfortran.target/aarch64/pr122408_1.f90: Update the fcmla
rotation counts.
The autoprofile bootstrap support probes for Arm SPE from gcc/configure,
gcc-auto-profile, and the profile-optimization testsuite support. Each
bare "perf list" scans every event class even though arm_spe is a PMU.
This can make the probe unnecessarily slow on systems with many events.
Use "perf list pmu" at all three call sites. The PMU event class filter
has long been supported by perf and still reports arm_spe. Stubbed BRBE,
SPE, and fallback paths select the same profiler as before.
This patch actually saves a few minutes of end-to-end bootstrap time on my SPE
AArch64 many-core system.
gcc/ChangeLog:
* config/aarch64/gcc-auto-profile: Probe for arm_spe with
"perf list pmu" instead of "perf list".
* configure.ac: Likewise.
* configure: Regenerate.
contrib: add support for tabs in the middle of the line
When running the style checker, it can incorrectly, report an error for
too wide lines if the tab is not at the start of the line.
In below example, I'm using ^I to visualise a tab.
bool begun;^I^I^I^I/* True if begin initialized output state. */
Without this patch, the line above is reported to be longer than 80
characters, but it's only 78 characters long. With the patch, its
correct length is used and the check passes.
contrib/ChangeLog:
* check_GNU_style_lib.py: Use visual tab size rather than
blindly using 8 spaces as replacement.
Hongyu Wang [Tue, 28 Jul 2026 03:41:37 +0000 (11:41 +0800)]
i386: Merge duplicate preferred_for_speed attributes on QImode NDD patterns
Several QImode integer patterns has two separate attr "preferred_for_speed"
set, one gating the NDD memory-form alternatives with
TARGET_ENABLE_NDD_MEM, and the existing one is for !TARGET_PARTIAL_REG_STALL.
The later one will make genattrtab regenerates the cond based on
!PARTIAL_REG_STALL only and overrides the TARGET_ENABLE_NDD_MEM, so the NDD
memory alternatives were always preferred for speed regardless of the
X86_TUNE_ENABLE_NDD_MEM enabled or disabled.
Combine both conditions into a single preferred_for_speed cond per
pattern. For *ashlqi3_1 alternative 5 belongs to both sets, so it is
gated on TARGET_ENABLE_NDD_MEM && !TARGET_PARTIAL_REG_STALL.
gcc/ChangeLog:
* config/i386/i386.md (*addqi_1<nf_name>): Merge the two
preferred_for_speed attributes into one.
(*andqi_1<nf_name>): Likewise.
(*andqi_2_maybe_si): Likewise.
(*<code>qi_1<nf_name>): Likewise.
(*notxorqi_1): Likewise.
(*one_cmplqi2_1): Likewise.
(*ashlqi3_1<nf_name>): Likewise.
Reshma Roy [Tue, 28 Jul 2026 11:25:24 +0000 (16:55 +0530)]
x86_cse: Check if DRAP is live with DF_LR_IN.
The DRAP register has no reaching definition on function entry, so it
never shows up in DF_LIVE_IN. When collecting the live caller-saved
registers, additionally set DRAP's bit whenever it is live-in per
DF_LR_IN, so the hoisted TLS call is kept after the DRAP save.
PR target/126382
gcc/ChangeLog:
* config/i386/i386-features.cc (ix86_emit_tls_call): Additional
check to see if DRAP register is live in basic block with DF_LR_IN.
James K. Lowden [Tue, 28 Jul 2026 21:35:55 +0000 (17:35 -0400)]
cobol: Consolidate parsing of Level 78 constants and ISO 01 constants.
MF-defined Level 78 constants were handled "specially" and in some
cases incorrectly. They are now treated as merely syntactically
different. The logic for both is the same.
gcc/cobol/ChangeLog:
* parse.y: Remove value78 nonterminal, introduce
level_constant nonterminal for all constants. Move validation
to level_constant. Remove other special handling for Level 78.
* scan_post.h (prelex): Correct Level 78/88 typo.
James K. Lowden [Tue, 28 Jul 2026 19:26:33 +0000 (15:26 -0400)]
cobol: Cleanse lexer of "dangerous trailing context" warnings.
Remove r/s patterns from scan.l where they provoke warnings, notably
while scanning a PICTURE in the field_state start condition. Instead,
scan rs and then find the end of r in user action. Adjust location
and scanner position accordingly.
Revise parser picture-validation to use new lexer token sequence.
Add unimplemented diagnostic for XML GENERATE. Fixes RT 3580.
Also answer gcc warning by not including <stdbool> .
gcc/cobol/ChangeLog:
* cbldiag.h (location_dump): Only declare function.
* parse.y: Update numeric PICTURE parse, and better diagnostic.
* scan.l: Rewrite numeric and numeric-edited PICTURE scan.
* scan_ante.h (myless): Use "unique" local variable name.
(length_upto): New function.
(is_name_char): New function.
(length_of_name): New function.
(trim_location): Set location endpoint by addition, not subtraction.
(ndigit): Allow 'V' at beginning or end of PICTURE string.
* util.cc (gcc_location_set): Indentation, and more verbose debugging.
(yy_flex_debug): Undefine tree.h symbol.
(location_dump): Define function in .cc file, now public.
libgcobol/ChangeLog:
* io.cc: Remove reference to cstdbool, now obsolete.
We want to use difference expressions in the .eh_frame section for
EH encoding but gas defines CFI_DIFF_EXPR_OK to 0. So, we need to
disable generation of CFI directives on hppa*-*-hpux*. GCC will
generate the difference expressions itself.
2026-07-28 John David Anglin <danglin@gcc.gnu.org>
gcc/ChangeLog:
* configure.ac: Set gcc_cv_as_cfi_directive to no on
hppa*-*-hpux*.
* configure: Regenerate.
... in order to replace runtest_file_p with a version that returns true
if the test, besides the usual check, also falls into the partition a
given parallelized runtest instance executes.
This meant that each call to runtest_file_p was incrementing the
partition counter twice (because it called gcc_parallel_test_run_p
twice; once through gcc_parallelize_saved_runtest_file_p - which now
became the gcc-defs copy of the replaced runtest_file_p - and once
directly).
The copy of this logic in libstdc++ is supposed to be identical (and
indeed was up to an accidental divergence as a result of copy-pastery)
to the one in gcc-defs, so we simply remove the former.
gcc-defs also defines other things that have parallels in the libstdc++
testsuite logic. To avoid clobbering the libstdc++ definitions, I've
moved the load_libs that loaded them later.
This seems to have been the intention (a comment above the load_lib
block states "compiler routines, then ours") at some point.
It may be worth looking into this again to see whether we can
deduplicate more code. But, when I looked at it, the logic seemed
distinct enough not to risk removing it for now.
libstdc++-v3/ChangeLog:
* testsuite/lib/libstdc++.exp: Load gcc-defs.exp. Load
prune.exp and dg-options.exp after GCC testsuite libs.
(libstdc++_init): Use gcc-set-multilib-library-path to calculate
LD_LIBRARY_PATH for installed G++ compilers.
When a subprocess (say, lto1) gets killed by SIGKILL on Linux with
LANG=en_..., the message GCC prints is "Killed signal terminated program
lto1".
This message is a little bit unclear - the "Killed" is certainly not
something that gramatically fits there, and the syscall for sending a
signal is called "kill", so the above sounds like an incorrect way of
saying "program lto1 was killed by some signal".
I can't find any decent description of what the correct class of words
strsignal returns, so, lets instead print "PROG terminated by signal
9 (Killed)". This is clearer; it states that signal 9 is at fault and
gives the OS-provided "descriptive string" corresponding to that signal.
Example:
~/gcc/_b_gcc/gcc$ ./xgcc -B. -x c -
xgcc: fatal error: cc1 terminated by signal 9 (Killed)
compilation terminated.
~/gcc/_b_gcc/gcc 1 $
gcc/ChangeLog:
* gcc.cc (execute): Make "signal terminated program" message
clearer.
Suggested-by: Alexander Monakov <amonakov@ispras.ru>
[frange] Store a single sub-range in an array slot.
To prepare for holding more than one sub-range, move the endpoints
m_min/m_max into a one-element array.
While here, pick the low-hanging multi-range fruit so the follow-up
patches stay small: consumers that walk every sub-range now loop over
m_num_ranges, and the inherently single-range ones (normalize_kind,
singleton_p, etc) gain an m_num_ranges == 1 guard. The hard cases
(union_/intersect, etc) are left with FIXMEs for later.
No change to functionality as MAX_PAIRS is 1. I'll bump this to 2 in
a subequent patch, and implement union/intersect and all the other
little things.
Tested on ppc64le Linux. No change to assembly over the LAPACK
preprocessed-Fortran corpus; LAPACK and GCC tests pass.
gcc/ChangeLog:
* value-range.h (struct frange_pair): New.
(class frange): Replace m_min and m_max with m_pairs[MAX_PAIRS]
and m_num_ranges. Add MAX_PAIRS, num_pairs, and the indexed
lower_bound and upper_bound. Have canonicalize_zeros take an
frange_pair.
(frange::lower_bound, frange::upper_bound): Adjust.
(frange::set_varying, frange::set_undefined, frange::set_nan)
(frange::known_isfinite, frange::known_isnormal)
(frange::known_isdenormal_or_zero, frange::maybe_isinf)
(frange::known_isinf, frange::signbit_p): Adjust.
* value-range.cc (frange::flush_denormals_to_zero): Adjust.
(frange::canonicalize_zeros): Take an frange_pair.
(frange::set, frange::normalize_kind, frange::union_nans)
(frange::union_, frange::intersect, frange::operator=)
(frange::operator==, frange::contains_p)
(frange::internal_singleton_p, frange::singleton_p)
(frange::verify_range, frange::zero_p): Adjust.
* value-range-storage.h (class frange_storage): Replace m_min
and m_max with m_pairs and m_num_ranges.
* value-range-storage.cc (frange_storage::set_frange): Adjust.
(frange_storage::get_frange): Adjust.
analyzer: support vfunc devirtualization [PR97114]
The analyzer doesn't currently support virtual function call resolution,
and has no way to devirtualize concrete calls.
This patch adds support for devirtualization of virtual methods by
adding logic around OBJ_TYPE_REF calls and using the information it
tracks to link the calls back to the concrete subclass implementation
stored in the OBJ_TYPE_REF_OBJECT's vptr field.
This approach relies on the pre-existing store binding mechanism to keep
track of which _ZTV* instance the object's vptr field points to, and
thus doesn't require any additional modeling of the dynamic type of the
object to resolve calls.
can_throw_p is also extended to consider thunks that wrap virtual
methods when dealing with multiple inheritance, and now checks
TREE_NOTHROW for more accurate results (i.e considers noexcept
attributes on methods).
PR analyzer/97114
gcc/analyzer/ChangeLog:
* region-model.cc (can_throw_p): improve NOTHROW detection and
consider the thunk case.
(region_model::get_fndecl_for_virtual_call): New function.
(region_model::get_fndecl_for_call): Update to use
get_fndecl_for_virtual_call on OBJ_TYPE_REF.
* region-model.h (class region_model): New decl.
gcc/testsuite/ChangeLog:
* g++.dg/analyzer/devirt-1.C: New test.
* g++.dg/analyzer/devirt-multiple-inheritance-1.C: New test.
* g++.dg/analyzer/devirt-noexcept-1.C: New test.
* g++.dg/analyzer/devirt-unknown-1.C: New test.
Richard Ball [Tue, 28 Jul 2026 14:53:36 +0000 (15:53 +0100)]
aarch64: Add support for sve2p3 and sme2p3 conversion intrinsics
This patch adds support for new intrinsics which make use of
the conversion instructions introduced in SVE2p3/SME2p3.
gcc/ChangeLog:
* config/aarch64/aarch64-acle-builtins.h
(TYPES_cvtzn): New function types.
(TYPES_cvttb): Likewise.
(cvtzn): Likewise.
(cvttb): Likewise.
* config/aarch64/aarch64-sve-builtins-sve2.cc
(class svcvtt_impl): New function impl.
(class svcvtb_impl): Likewise.
(FUNCTION): Likewise.
* config/aarch64/aarch64-sve-builtins-sve2.def
(svcvtn): New function.
(svcvtt): Likewise.
(svcvtb): Likewise.
* config/aarch64/aarch64-sve-builtins-sve2.h: Likewise.
* config/aarch64/aarch64-sve2.md
(@aarch64_sve2_scvtfb<mode>): New pattern.
(@aarch64_sve2_scvtflt<mode>): Likewise.
(@aarch64_sve2_ucvtfb<mode>): Likewise.
(@aarch64_sve2_ucvtflt<mode>): Likewise.
(@aarch64_sve2_fcvtzsn<mode>): Likewise.
(@aarch64_sve2_fcvtzun<mode>): Likewise.
* config/aarch64/iterators.md
(b): Ventype changes.
(VNx16HF): Likewise.
(VNx16QI): Likewise.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/sme2/acle-asm/cvtb_f16_s8.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtb_f16_u8.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtb_f32_s16.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtb_f32_u16.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtb_f64_s32.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtb_f64_u32.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtn_s16_f32_x2.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtn_s32_f64_x2.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtn_s8_f16_x2.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtn_u16_f32_x2.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtn_u32_f64_x2.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtn_u8_f16_x2.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtt_f16_s8.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtt_f16_u8.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtt_f32_s16.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtt_f32_u16.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtt_f64_s32.c: New test.
* gcc.target/aarch64/sme2/acle-asm/cvtt_f64_u32.c: New test.
* config/aarch64/aarch64-c.cc
(aarch64_update_cpp_builtins): New target flag.
* config/aarch64/aarch64-simd-builtins.def: New functions.
* config/aarch64/aarch64-simd.md
(sdot_prod<VDQSF:vsi2qi><vczle><vczbe>): New pattern.
(sdot_lane<VF:isquadop><VDQSF:vsi2qi><vczle><vczbe>): Likewise.
* config/aarch64/aarch64.h
(TARGET_F16F32DOT): New target flag.
* config/aarch64/arm_neon.h
(target): Add f16f32dot section.
(__attribute__): New builtin function calls.
(vdot_f32_f16): Likewise.
(vdotq_f32_f16): Likewise.
(vdot_lane_f32_f16): Likewise.
(vdot_laneq_f32_f16): Likewise.
(vdotq_lane_f32_f16): Likewise.
(vdotq_laneq_f32_f16): Likewise.
* config/aarch64/iterators.md
(q): New options for isquadop.
* doc/invoke.texi: Add f16f32dot.
gcc/testsuite/ChangeLog:
* lib/target-supports.exp: New check_effective_target.
* gcc.target/aarch64/advsimd-intrinsics/fdot-1.c: New test.
* gcc.target/aarch64/advsimd-intrinsics/fdot-2.c: New test.
* gcc.target/aarch64/advsimd-intrinsics/fdot-3.c: New test.
This adds 64-bit saturated fixed-point divisions to lib1funcs-fixed.S.
The ordinary divisions are just aliases of the saturating ones.
Rounding is towards zero.
Richard Ball [Tue, 28 Jul 2026 13:45:01 +0000 (14:45 +0100)]
aarch64: Add Support for SVE2p3/SME2p3 dot product intrinsics
Add support for SVE2p3 and SME2p3 dot product intrinsics
gcc/ChangeLog:
* config/aarch64/aarch64-acle-builtins.h
(TYPES_s_narrow_su): New type array.
(s_narrow_su): Likewise.
* config/aarch64/aarch64-sve-builtins-base.cc
(class svdot_impl): Update impl.
(FUNCTION): Likewise.
* config/aarch64/aarch64-sve-builtins-sve2.def
(REQUIRED_EXTENSIONS): New function.
(svdot): Likewise.
(svdot_lane): Likewise.
* config/aarch64/aarch64-sve2.md
(<sur>dot_prodvnx4sivnx8hi): Renamed.
(@<sur>dot_prod<VNx4SI_ONLY:mode><VNx8HI_ONLY:mode>): New Name.
(@<sur>dot_prod<VNx8HI_ONLY:mode><VNx16QI_ONLY:mode>): New pattern.
(@aarch64_<sur>dot_prod_lane<VNx8HI_ONLY:mode><VNx16QI_ONLY:mode>): Likewise.
* config/aarch64/aarch64.h
(TARGET_SVE2p3): New Target Flag.
(TARGET_SME2p3): Likewise.
(TARGET_STREAMING_SME2p3): Likewise.
(TARGET_SVE2p3_OR_SME2p3): Likewise.
* doc/invoke.texi: Add sve2p3/sme2p3.
gcc/testsuite/ChangeLog:
* lib/target-supports.exp: New check_effective_targets.
* gcc.target/aarch64/sme2/acle-asm/dot_lane_s16.c: New test.
* gcc.target/aarch64/sme2/acle-asm/dot_lane_u16.c: New test.
* gcc.target/aarch64/sme2/acle-asm/dot_s16.c: New test.
* gcc.target/aarch64/sme2/acle-asm/dot_u16.c: New test.
* gcc.target/aarch64/sve2/dotproduct_intrinsicless.c: New test.
CTZ pattern recognition can recurse through a temporary pattern
stmt but that will fail to be detected as part of a reduction
because the setup is partial. This causes the reduction chain
to break due to multiple uses. Avoid recursing in case the original
pattern is for a reduction.
PR tree-optimization/126404
* tree-vect-patterns.cc (vect_recog_popcount_clz_ctz_ffs_pattern):
Avoid recursing to vect_recog_ctz_ffs_pattern with a reduction.
H.J. Lu [Sun, 26 Jul 2026 11:21:55 +0000 (19:21 +0800)]
vectorizer: Don't enlarge base alignment during costing
We errorneously commit the recorded base alignment during costing
since the costing refactoring. This causes alignment to be
computed based on a possibly larger vector type than used in the
end.
gcc/
PR middle-end/126410
* tree-vect-stmts.cc (vectorizable_store): Only commit to
recorded base alignment when transforming.
(vectorizable_load): Likewise.
David Faure [Mon, 27 Jul 2026 18:02:29 +0000 (20:02 +0200)]
libstdc++: Fix num_children of the map pretty-printers
StdMapPrinter and Tr1UnorderedMapPrinter yield a separate child for the
key and for the value of every element, as their 'map' display hint
requires, but their num_children methods return the number of elements,
i.e. half of what children() produces.
GDB counts the children itself where it does not use num_children, so
the two disagree about the same map. For a std::map with 2 elements:
(gdb) interpreter-exec mi "-enable-pretty-printing"
(gdb) interpreter-exec mi "-var-create v * m"
(gdb) interpreter-exec mi "-var-list-children v"
^done,numchild="4",displayhint="map",children=[...]
while num_children() returns 2. The DAP code in gdb treats the two as
interchangeable: gdb/python/lib/gdb/dap/varref.py calls num_children()
when the printer has one, and falls back to len(list(children())) when
it does not, so a DAP client sees half the children of a std::map,
std::multimap or std::unordered_map.
StdSetPrinter and the sequence container printers yield one child per
element, so they are correct as they are.
libstdc++-v3/ChangeLog
* python/libstdcxx/v6/printers.py (StdMapPrinter.num_children):
Count two children per element.
(Tr1UnorderedMapPrinter.num_children): Likewise.
Signed-off-by: David Faure <david.faure@kdab.com> Reviewed-by: Tom Tromey <tromey@adacore.com>
David Faure [Mon, 27 Jul 2026 17:13:43 +0000 (19:13 +0200)]
libstdc++: Fix parameter name in map/set printer num_children
StdMapPrinter.num_children and StdSetPrinter.num_children name their
parameter 'slf' but refer to 'self' in the body, so any call raises
"NameError: name 'self' is not defined".
GDB does not call num_children for a plain 'print', which is why this
went unnoticed, but printers that delegate to these ones do hit it.
For instance KDevelop's QMap pretty-printer forwards to StdMapPrinter,
and fails with the above error on every Qt 6 QMap since these methods
were added in commit de124ffe1439.
cfgexpand: Verify that partitions do not share a MEM_EXPR [PR126405]
Two stack slots carrying one MEM_EXPR read as a single object to
MEM_EXPR-based disambiguation. That is how PR121957, PR123625 and PR126405
each became wrong code: the load/store pair-fusion pass identifies a location
by a MEM_EXPR base and an offset from it, so it fused accesses that belong to
different slots and redirected a store.
out-of-SSA maintains the invariant, but a break in it stays silent until some
consumer acts on it, and only for the subset of functions that consumer happens
to look at.
Check it directly once per function under flag_checking, after every partition
has been given its RTL, so that a regression here is an ICE rather than a
miscompile.
Bootstrapped and tested on aarch64-none-linux-gnu and x86_64-linux-gnu.
gcc/ChangeLog:
PR middle-end/126405
* cfgexpand.cc (verify_partition_mem_exprs): New function.
(pass_expand::execute): Call it.
out-of-SSA: Split partitions of parameters and results too [PR126405]
split_overlapping_partition_decls left PARM_DECLs and RESULT_DECLs alone, on
the grounds that they need a single partition holding the canonical RTL. That
partition is the one of the default definition, which the rule already in place
keeps, so the exclusion was wider than it needed to be.
A parameter that stays live across a redefinition of itself needs two
partitions, and an oversized vector parameter puts both of them in memory: the
incoming argument slot and a local slot. Every name of both partitions has the
PARM_DECL as its base, so both slots are given it as their MEM_EXPR:
Two addresses claiming to be p+0 let the load/store pair-fusion pass fuse
accesses that belong to different slots, which miscompiles the new test on
aarch64 at -Os.
Drop the exclusion. SSA_NAME_VAR is a VAR_DECL, a PARM_DECL or a RESULT_DECL
and set_rtl attaches any of them, so all three need the same treatment. The
rename leaves default definitions alone, so the partition holding one still
owns the canonical RTL.
Bootstrapped and tested on aarch64-none-linux-gnu and
x86_64-pc-linux-gnu.
gcc/ChangeLog:
PR middle-end/126405
* tree-outof-ssa.cc (split_overlapping_partition_decls): Also split
partitions of PARM_DECLs and RESULT_DECLs.
gcc/testsuite/ChangeLog:
PR middle-end/126405
* gcc.c-torture/execute/pr126405-3.c: New test.
out-of-SSA: Use all partition names to find the decl to split [PR126405]
split_overlapping_partition_decls gives every partition but one of a
memory-resident VAR_DECL its own artificial decl, so that distinct stack slots
do not end up sharing a MEM_EXPR. It takes the variable of a partition from
that partition's representative. set_rtl attaches the base variable of any
name in a partition to that partition's location, so the variable a partition
is given need not be the one of its representative.
Here the partition holding the loop-carried versions of an oversized vector
temporary has an anonymous representative:
Partition 1 (_2 - 2 14 16 ) _2 has no base variable, while
14 and 16 are g18_lsm.11_14 and _16
Partition 30 (g18_lsm.11_41 - 41 )
Partition 1 is skipped because SSA_NAME_VAR of _2 is null, so partition 30
believes it is the only partition of g18_lsm.11 and keeps the user decl. Both
128 byte slots then get MEM_EXPR g18_lsm.11. The load/store pair-fusion pass
groups accesses by MEM_EXPR base and MEM_OFFSET, so it treated two stores that
are 144 bytes apart as adjacent and fused them:
after (set (mem:V2x16QI [sp+240])
(unspec [(reg v17) (reg v27)] UNSPEC_STP))
[sp+384] is never written.
Work out the variable each partition will be given and key the keep/split
decision on that, reusing the function set_rtl makes the same choice with,
renamed to expand_leader_merge now.
That function keeps the variable it is given first unless
a later one is DECL_IGNORED_P, and expansion hands set_rtl the representative
before the other names, so the representative's variable goes in first.
A partition holding names of two variables would otherwise be keyed on the
wrong one.
Bootstrapped and tested on aarch64-none-linux-gnu.
gcc/ChangeLog:
PR middle-end/126405
* cfgexpand.cc (leader_merge): Rename to...
(expand_leader_merge): ...this. Make external.
* cfgexpand.h (expand_leader_merge): Declare.
* tree-outof-ssa.cc: Include cfgexpand.h.
(split_overlapping_partition_decls): Determine the variable of a
partition from all of its names.
gcc/testsuite/ChangeLog:
PR middle-end/126405
* gcc.c-torture/execute/pr126405.c: New test.
* gcc.c-torture/execute/pr126405-2.c: New test.
* gcc.dg/pr126405-1.c: New test.
* gcc.dg/pr126405-2.c: New test.
* gcc.dg/pr126405-3.c: New test.
i386: Avoid XCHGB %rH, %rL in bswaphi2 on non-pentium4 targets [PR126433]
XCHGB has higher latency than ROLW for non-pentium4 targets, so it
should be avoided. Switch from the preferred_for_size/preferred_for_speed
attributes to the "enabled" attribute to hard-disable unwanted alternatives.
PR target/126433
gcc/ChangeLog:
* config/i386/i386.md (*bswaphi2_movbe) Use enabled attribute.
Remove preferred_for_speed and preferred_for_size attributes.
(*bswaphi2): Ditto.
(*bswaphisi2_lowpart): Ditto.
gcc/testsuite/ChangeLog:
* gcc.target/i386/xchg-1.c: Scan for ROL instead of XCHG.
* gcc.target/i386/xchg-2.c: Use -O2 -march=pentium4 to emit XCHG.
middle-end: look through VEC_DUPLICATE_EXPR in ssa_uniform_vector_p
ssa_uniform_vector_p is documented as returning the element a uniform
vector is a splat from, and it handles VEC_DUPLICATE_EXPR when it is
handed the bare tree. It did not handle the much more common gimple
form, where the splat is the RHS of an SSA definition: VEC_DUPLICATE_EXPR
is a unary operation, so gimple_assign_single_p is false for it and the
SSA_NAME path fell through to NULL_TREE.
Splats started reaching the helper in that form with r17-2019-g770ff476d06f ("aarch64: Port NEON vector creation intrinsics to
pragma-based framework"), after which vdup_n_u8 and friends fold to
uniform_vec_5 = [vec_duplicate_expr] _1;
rather than to a CONSTRUCTOR, so ssa_uniform_vector_p stopped seeing
through them. Callers that lose out are the lowpart-to-highpart NEON
builtin fold in the aarch64 back end, vector shift and division
lowering in tree-vect-generic.cc, and the CONSTRUCTOR-of-splats
simplification in tree-ssa-forwprop.cc.
For gcc.target/aarch64/simd/fold_to_highpart_7.c this restores
I messed up and checked the vector type instead of the reduction
number of lanes.
PR tree-optimization/126417
* tree-vect-slp.cc (vectorizable_bb_reduc_epilogue): Check
the total number of lanes instead of the vector type against
the two-lane special case that doesn't need fold-left reduction
handling.
Andrea Pinski [Mon, 27 Jul 2026 22:06:07 +0000 (15:06 -0700)]
testsuite: Add C++ testcase for PR 126296: `<=>` folding into `<>`.
This adds 2 testcases for fp: `(i <=> j > 0) | (i <=> j < 0)`.
The trapping version was fixed by r17-2709-gde8be0eb05d951
while the non-trapping version was fixed earlier by r17-2129-gea8c74c074925b.
Since we didn't have a testcase for these cases before,
it would be a good idea to have them.
Pushed as obvious after testing to make sure they work on x86_64-linux-gnu.
PR tree-optimization/126296
gcc/testsuite/ChangeLog:
* g++.dg/tree-ssa/pr126296-1.C: New test.
* g++.dg/tree-ssa/pr126296-2.C: New test.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
James K. Lowden [Mon, 27 Jul 2026 16:30:17 +0000 (12:30 -0400)]
cobol: Resume source format after copybook ends.
The ISO CDF SOURCE FORMAT directive controls interpretation of the ensuing
source code, including copybook files until EOF. At the end of a
copybook, any changes it made to the SOURCE FORMAT status is
discarded.
The scanner determines whether or not Debugging Mode ('D' in column 7)
lines are included. Because it does not know the source format, for
Reference Format files the lexio module replaces the 'D' with 0x8D,
which to the scanner signifies a Debug line.
gcc/cobol/ChangeLog:
* cbldiag.h (cdf_push_source_format): Remove declaration.
(cdf_pop_source_format): Same.
* cdf-copy.cc (is_fixed_format): Same.
(is_reference_format): Same.
(esc): Pass new format parameter and use new 0x8D Debug indicator.
* cdf.y: Ignore SOURCE FORMAT directive (handled in lexio.cc).
* lexio.cc (cdf_source_format): Delete function definition.
(source_format_t::infer): Same.
(is_fixed_format): Same.
(is_reference_format): Same.
(left_margin): Same.
(right_margin): Same.
(include_debug): Assume fixed format.
(set_debug): Same.
(continues_at): Remove unused function.
(indicated): Move function to source_format_t class.
(source_format_t::indicated): Replace ::indicated().
(filespan_t::tab_check): Delete function.
(check_push_pop_directive): Add format stack parameter.
(check_source_format_directive): Same.
(esc): Add format parameter and use 0x8D indicator.
(parse_replace_pairs): Add format parameter.
(parse_copy_directive): Same.
(parse_replace_text): Same.
(parse_replace_directive): Same.
(cdftext::lex_open): Instantiate and pass format stack.
(cdftext::free_form_reference_format): Add format stack parameter and 0x8D indicator.
(cobol_set_indicator_column): Stash command-line option.
(cdftext::process_file): Add format stack parameter.
* lexio.h (struct filespan_t): Remove tab_check() function.
(class source_format_t): Lift into header file to share with cdf-copy.cc.
(class cdftext): Add several functions, formerly file-scope.
(free_form_reference_format): Move to source_format_t.
* parse.y: Slightly simplify parse of WITH DEBUGGING MODE.
* scan.l: Recognize new 0x8D indicator.
* scan_ante.h (cobol_set_indicator_column): Remove declaration.
* util.cc (class cdf_directives_t): Remove source format support.
(cobol_set_indicator_column): Move function to lexio.cc.
(cdf_source_format): Delete function.
(cdf_push_source_format): Same.
(cdf_pop_source_format): Same.
* util.h (class source_format_t): Move to lexio.h.
OpenMP: Fortran + ME - update for spatial dimensions + message clause
Add 'message' + 'severity' clause to target, teams, and parallel.
Translate those and handle strict/dims modifiers to num_teams, thread_limit
and num_threads - the latter also permits multiple values without 'dims'.
With this commit, the 'sorry, unimplemented' is moved from the Fortran
front end to the middle end (omp-expand.cc). Note that parser support
for C and C++ still has to be added.
gcc/fortran/ChangeLog:
* dump-parse-tree.cc (show_omp_clauses): Fix 'message' clause name.
* openmp.cc (gfc_match_omp_clauses): Improve num_team's error
diagnostic.
(OMP_PARALLEL_CLAUSES, OMP_TARGET_CLAUSES, OMP_TEAMS_CLAUSES): Add
OMP_CLAUSE_MESSAGE and OMP_CLAUSE_SEVERITY.
* trans-openmp.cc (gfc_split_omp_clauses): Handle message/severity.
(gfc_trans_omp_clauses): Likewise; replace 'sorry' by updated tree
generation for num_teams, num_threads, thread_num clauses.
gcc/ChangeLog:
* gimplify.cc (gimplify_scan_omp_clauses): Handle also TREE_LIST
for num_teams, num_threads, thread_num clauses. Add message clause
to switch statement.
* omp-expand.cc (expand_parallel_call, expand_teams_call,
get_target_arguments): Handle, mostly with 'sorry, unimplemented',
the 'dims' and 'strict' modifiers and the 'message' clause.
* omp-low.cc (scan_sharing_clauses): Add message clause to switch.
(lower_omp_teams): Handle TREE_LIST for num_threads + thread_num.
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_MESSAGE.
* tree-pretty-print.cc (dump_omp_clause): Handle 'message' clause,
update num_teams, num_threads, thread_num clause printing.
* tree.cc (omp_clause_num_ops, omp_clause_code_name): Update for
message clause.
* tree.h (OMP_CLAUSE_NUM_THREADS_STRICT,
OMP_CLAUSE_THREAD_LIMIT_STRICT, OMP_CLAUSE_NUM_TEAMS_DIMS,
OMP_CLAUSE_NUM_THREADS_DIMS, OMP_CLAUSE_THREAD_LIMIT_DIMS,
OMP_CLAUSE_MESSAGE_EXPR, OMP_CLAUSE_MESSAGE_LEN,
OMP_CLAUSE_MESSAGE_SEVERITY_WARN): New.
gcc/testsuite/ChangeLog:
* gfortran.dg/gomp/spatial-dimensions-1.f90: Move to gimple dumps
and extend tree-dump checking.
* gfortran.dg/gomp/spatial-dimensions-2.f90: Remove sorry and
check omplower and ompexp tree dumps.
* gfortran.dg/gomp/spatial-dimensions-3.f90: Update dg-error.
* gfortran.dg/gomp/spatial-dimensions-4.f90: New test.
* gfortran.dg/gomp/spatial-dimensions-5.f90: New test.
Jakub Jelinek [Mon, 27 Jul 2026 16:54:37 +0000 (18:54 +0200)]
fortran: Fix ICE with loops with (deprecated) non-integral iterators [PR126303]
do_subscript contains
do_sym = dl->ext.iterator->var->symtree->n.sym;
if (do_sym->ts.type != BT_INTEGER)
continue;
check to ignore loops with non-integral iterator. But r15-11154
PR94978 change has added inner_loop_may_be_skipped function and that
happily accesses inner loop iterator's step, start and end if EXPR_CONSTANT
with mpz_init_set (..., ...value.integer);
Now, given the layout of mpfr_t (usually long, int, long, pointer)
and mpz_t (usually int, int, pointer), this sometimes just produces silently
garbage (e.g. on 64-bit little-endian, where the second int in mpz_t is
the most significant 32-bits of _mpfr_prec and so usually 0 and so _mp_size
is 0 and nothing is dereferenced:
p loop->ext.iterator->step.value.real
$1 = {{_mpfr_prec = 24, _mpfr_sign = 1, _mpfr_exp = 1, _mpfr_d = 0x4eac658}}
p loop->ext.iterator->step.value.integer
$2 = {{_mp_alloc = 24, _mp_size = 0, _mp_d = 0x1}}
or it ICEs somewhere in gmp (on 32-bit little-endian, e.g. i686, or
big-endian, e.g. s390x), because _mp_size is in that case _mpfr_sign but
_mp_d is _mpfr_exp (32-bit little-endian), or _mp_size is least significant
part of _mpfr_prec, in both cases non-zero, but _mp_d is not a usable
pointer in either case.
The following patch fixes that by punting for inner loops with non-integral
iterator.
2026-07-27 Jakub Jelinek <jakub@redhat.com>
PR fortran/126303
* frontend-passes.cc (inner_loop_may_be_skipped): If inner loop iterator
is not integral, return true.
* gfortran.dg/pr126303.f: New test.
Reviewed-by: Jerry DeLisle <jvdelisle@gcc.gnu.org>
testsuite/aarch64: use a relative tolerance in vect-vaddv.c
The test builds a reference sum by adding the elements in order and
compares it against the vaddv reduction with an absolute tolerance of
1e-6. vaddvq_f32 expands to two faddp, i.e. a pairwise sum, so the two
sides associate differently and agree only to within a few ULP. At the
magnitudes in input_float32[] one float32 ULP is 6.1e-5 to 2.4e-4, tens
to hundreds of times larger than the tolerance, so the comparison only
ever passed when both sides happened to round the same way.
The test compiles with -ffast-math, and since r17-2478-g3adb33259541
("Improve BB vectorization of reductions", PR tree-optimization/126028)
the reference chain is reassociated too, which changes the rounding and
the test aborts in test_vaddvf32_float32x4_t. That commit removed the
forced-even-lane trim in vect_slp_check_for_roots and added the
non-matching-lane split retry in vect_build_slp_instance, so the four
input_float32[] lanes are now discovered as a group once the out_l[0]
lane is split off. Both association orders are legal here and both land
within 1 ULP of the exact sum.
This is the third time the test has broken this way. PR testsuite/101506
added the asm barrier on the reference accumulator for the same reason.
Compare relatively instead. Every reference value in the test is
non-zero, so a plain relative test is safe, and at 1e-6 relative the
float32 checks still have about a factor of ten of margin over the
worst-case three-ULP reassociation error for this data.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/vect-vaddv.c (EQUALF, EQUALD): Compare
relative to the reference value.
testsuite/aarch64: restore the second lane-index error in mf8_data_2.c
vcopy_lane deliberately diagnoses both out-of-range lane indices: the
old pragma-builtins checker used & rather than && for exactly that
reason, and neon_shape::check keeps doing so. r17-2020-g4ff8e6ba9f4e ("aarch64: Port NEON lane get/set intrinsics to
pragma-based framework"), which moved vcopy_lane onto the new shape
framework, dropped the dg-error for the second index in the same commit,
so the test reports an excess error. The diagnostic behaviour is
identical before and after that port, so the deleted directive was
almost certainly a leftover from an intermediate revision of the patch.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/simd/mf8_data_2.c: Restore the dg-error for
the second out-of-range lane index of vcopy_lane_mf8.
testsuite/aarch64: accept either ubfx width in struct_3 test_nonpst8
r17-2413-ge46d96d20bbf ("PR middle-end/123236: Simplify (int)((long
long)x >> 4)") relaxed the guard on the truncate-of-extract
simplification in simplify_truncation, so combine can now narrow
to an SImode extract, and test_nonpst8 ends in ubfx w0 rather than
ubfx x0. Both compute the same 64-bit result in x0.
These blocks exist to check the SVE PCS handling of a non-pure-scalable
struct, so the width the extract happens to use is incidental. Accept
either rather than swapping one hard-coded width for the other, so the
test does not break again the next time the narrowing decision moves.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/sve/pcs/struct_3_128.c (test_nonpst8): Accept
a ubfx of either width.
* gcc.target/aarch64/sve/pcs/struct_3_256.c (test_nonpst8):
Likewise for little endian.
testsuite/aarch64: accept either csel polarity in fuse_cmp_csel tests
These tests exist to check that the compare and the csel stay adjacent so
that the Neoverse V2 CMP+CSEL fusion can fire. The condition code itself
is incidental: for a > b ? d : e either polarity is correct, costs the
same three instructions, and keeps the pair adjacent, and
aarch_macro_fusion_pair_p does not look at the condition.
fuse_cmp_csel-1.c was added by r17-1507-gc43fed44d9ac ("phiopt: Allow
factoring out of more than just single operand operations") with a gt
expectation, and the same commit switched the existing fuse_cmp_csel.c
directives from le to gt. Eight days later r17-1571-ga05a055bb2fb
("phiopt: reorganize factoring/cselim-limited for phiopt") made
pass_phiopt return TODO_cleanup_cfg when it factors, since factoring does
leave empty blocks behind. The diamond is now cleaned up one pass
earlier, crited1 re-splits the newly critical edge and the following
cleanup_cfg removes the other forwarder, leaving the mirror image of the
old CFG. Expand emits the inverted conditional jump and if-conversion
produces
cmp w0, w1
csel w3, w4, w3, le
so the gt expectation was stale almost as soon as it landed.
Rather than swap one hard-coded condition for another, accept both. That
keeps the tests pinned to what they are actually testing and stops them
breaking again the next time a middle-end change flips the CFG shape.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/fuse_cmp_csel-1.c: Accept csel with either
le or gt.
* gcc.target/aarch64/fuse_cmp_csel.c: Likewise.
Jakub Jelinek [Mon, 27 Jul 2026 11:20:01 +0000 (13:20 +0200)]
doc: Fix up doc build
The last change in sourcebuild.texi uses @code(...) which makeinfo
errors on:
sourcebuild.texi:2122: @code expected braces
sourcebuild.texi:2131: @code expected braces
Fixed thusly.
2026-07-27 Jakub Jelinek <jakub@redhat.com>
* doc/sourcebuild.texi (arm_neon_fp16_hw, arm_fp16_alternative_hw):
Use @code{...} instead of @code(...).
testsuite: arm: require fp16 alternative hw for tests
Currently, it's assumed that arm_fp16_alternative_ok is enough to run
the tests, but arm_fp16_alternative_ok allows multilib override. While
the test might link without trouble, execution will likely fail.
Add arm_fp16_alternative_hw to explicitly test that target can execute
fp16 instructions in alternative form.
Below tests are known to fail for
thumb/arch=armv7e-m+fp/cpu=cortex-m4/float-abi=hard/fpu=auto among other
targets.
gcc/ChangeLog:
* doc/sourcebuild.texi (arm_fp16_alternative_hw): Document.
(arm_neon_fp16_hw): Add reference to arm_neon_fp16_ok.
gcc/testsuite/ChangeLog:
* g++.dg/ext/arm-fp16/arm-fp16-ops-3.C: Require effective target
arm_fp16_alternative_hw instead of arm_fp16_alternative_ok.
* g++.dg/ext/arm-fp16/arm-fp16-ops-4.C: Likewise.
* gcc.dg/torture/arm-fp16-int-convert-alt.c: Likewise.
* gcc.dg/torture/arm-fp16-ops-3.c: Likewise.
* gcc.dg/torture/arm-fp16-ops-4.c: Likewise.
* lib/target-supports.exp (arm_fp16_alternative_hw): New proc.
Fold-left FP reductions are lowered to scalar operations on x86. In
mixed-width loops the per-statement costs can therefore make a wider
vector mode look better even though it lengthens the serial reduction
chain.
Count the fold-left reduction lanes from reduction groups and chains during
finish_cost and use that as an extra loop-candidate preference. Do not let
emulated sub-SSE modes win on this preference alone. Dump the lane count when
present.
gcc/ChangeLog:
* config/i386/i386.cc (ix86_vector_costs): Add
better_fold_left_reduc_than_p and m_num_fold_left_reduc_lanes.
(ix86_vector_costs::ix86_vector_costs): Initialize it.
(ix86_vector_costs::finish_cost): Count and dump fold-left
reduction lanes.
(ix86_vector_costs::better_fold_left_reduc_than_p): New function.
(ix86_vector_costs::better_main_loop_than_p): Use it.
(ix86_vector_costs::better_epilogue_loop_than_p): Likewise.
gcc/testsuite/ChangeLog:
* gcc.target/i386/fold-left-reduc-cost.c: New test.
* gcc.target/i386/fold-left-reduc-chain-cost.c: New test.
* gcc.target/i386/vect-epilogues-6.c: Update expected vector size.
* gcc.target/i386/vect-epilogues-7.c: Likewise.
* gcc.dg/vect/costmodel/x86_64/costmodel-vect-epil-1.c: Likewise.
Jason Merrill [Sun, 26 Jul 2026 16:44:22 +0000 (12:44 -0400)]
c++: vrp and pmf conversion [PR126310]
Here when trying to convert to EncodeFnTy, aka void (sub::*)(int&&), we were
instead converting to void (sub::*)(ValuePart&&), and the optimization added
by r16-5887 got confused by the values in the array initializer having
different RECORD_TYPEs (with different FIELD_DECLs) from the type of the
array.
So let's correct the conversion to actually end with the requested type.
PR c++/126310
gcc/cp/ChangeLog:
* call.cc (standard_conversion): Don't build a mixed METHOD_TYPE if
it isn't needed.
Robert Dubner [Mon, 27 Jul 2026 01:53:46 +0000 (21:53 -0400)]
cobol: Improve the creation of run-time arrays.
It's often the case that GENERIC creates arrays of values that are passed
to libgcobol routines. These changes improve how those arrays are created
and initialized with constructors. The main changes are to establish them
as const and to use current techniques for CONSTRUCTOR creation.
Jason Merrill [Fri, 24 Jul 2026 19:17:32 +0000 (15:17 -0400)]
c++: parse trivial DMI immediately [PR96645]
The current direction of CWG2335 is to parse complete-class contexts as
needed rather than always wait until the end of the outermost class.
This doesn't fully implement that (nor fully fix PR96645), but takes a step
in that direction by allowing simple cases that do no name lookup; then
being in complete class scope makes no difference.
CWG 2335
PR c++/96645
gcc/cp/ChangeLog:
* parser.cc (cp_parser_early_parsing_nsdmi): New.
(cp_parser_member_declaration): Call it.
c++: Fix ICE with loop pragmas at class scope [PR126323]
cp_parser_pragma rejected GCC loop pragmas at namespace scope, but not
at class scope. Consequently, it attempted to parse the following loop
as a statement while in a member-declaration context, leading to an ICE
when processing the loop initializer.
Patrick Palka [Sun, 26 Jul 2026 13:58:58 +0000 (09:58 -0400)]
libstdc++: Robustify flat_map::insert_range move counter test
Testing r17-2704-gf678da4a9930c8 on the 16 branch, which doesn't
implement P0401 std::allocate_at_least, revealed that the added test
isn't robust to std::vector initial capacity. The test needs to reserve
sufficient capacity upfront so that reallocation doesn't happen during
insert_range which would skew the move counter.
libstdc++-v3/ChangeLog:
* testsuite/23_containers/flat_map/1.cc (test14): Reserve
sufficient capacity for the underlying containers before
calling insert_range.
Pan Li [Fri, 24 Jul 2026 03:04:40 +0000 (11:04 +0800)]
RISC-V: Add test cases for vwaddu.wv reg overlap
Add test cases for register group overlap, please
note it is not overlap as much as possible.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u16-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u16-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u16-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u16-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u16-mf4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u32-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u32-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u32-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u32-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u8-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u8-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u8-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u8-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u8-mf4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_wv-u8-mf8.c: New test.
Pan Li [Fri, 24 Jul 2026 03:03:44 +0000 (11:03 +0800)]
RISC-V: Add test cases for vwadd.wv reg overlap
Add test cases for register group overlap, please
note it is not overlap as much as possible.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/group_overlap/group_overlap.h:
Add test helper macros.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i16-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i16-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i16-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i16-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i16-mf4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i32-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i32-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i32-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i32-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i8-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i8-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i8-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i8-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i8-mf4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_wv-i8-mf8.c: New test.
Andrea Pinski [Mon, 13 Jul 2026 22:20:09 +0000 (15:20 -0700)]
phiopt: New comparison combine part of phiopt [PR126138]
Since phiopt rejects trapping statements, this has to be done
seperately but it does reuse most of the infastructure to handle
this.
This is designed to handle foating point comparisons mergining
with another one.
An example is:
```
c = false;
if (a > b) c = a >= b;
```
This should merge into just `c = a > b;`.
Which we do already if it was written as `a > b && a >= b`.
In this case this is already handled by DOM/VRP/ranger.
The case I am more interesting in is:
```
bool f1(double a, double b)
{
if (a == b)
return 1;
return a > b;
}
```
Which can/should optimize to `a >= b`.
This comes from `(a <=> b) >= 0` without spaceship_replacement and/or
with a patch that forwprops the phi values into the `>= 0`; replacing
the phi.
That is this is prerequisite to
https://inbox.sourceware.org/gcc-patches/20260625233902.2605630-1-andrew.pinski@oss.qualcomm.com/.
and to remove spaceship_replacement in phiopt.
Bootstrapped and tested on x86_64-linux-gnu.
PR tree-optimization/126138
gcc/ChangeLog:
* tree-ssa-phiopt.cc (one_feeding_comparison_into_p): New function.
(comparison_combine): New function.
(pass_phiopt::execute): Call comparison_combine.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/fp-trapping-cmp-4.c: New test.
* gcc.dg/tree-ssa/fp-trapping-cmp-5.c: New test.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
We can sometimes combine comparisons that are trapping.
This adds that optimization to ifcombine; using combine_comparison
from fold-const to do most of the work.
This does not handle all cases though; mostly dealing with where we need an
inversion of the outer comparison and it does not invert is not currently handled.
This will be handled later on as it needs some extra code added to combine_comparisons.
Bootstrapped and tested on x86_64-linux-gnu.
PR tree-optimization/126138
gcc/ChangeLog:
* tree-ssa-ifcombine.cc (bb_no_side_effects_p): Don't reject GIMPLE_COND
that can trap.
(ifcombine_ifandif): Handle trapping inner conditional specially.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/fp-trapping-cmp-2.c: New test.
* gcc.dg/tree-ssa/fp-trapping-cmp-3.c: New test.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Andrea Pinski [Sun, 12 Jul 2026 05:56:40 +0000 (22:56 -0700)]
fold: Allow combining eq/ne with a trapping to get a trapping [PR126138]
For `(i == j) || (i < j)` this can be combined to just `i <= j` without
worrying about removal of a trap as a NaN would cause the the equal to be
false which will cause not to short circuit and the trapping instruction
will always be executed.
`(i != j) && (i < j)` has the same reasoning.
Bootstrapped and tested on x86_64-linux-gnu.
PR tree-optimization/126138
gcc/ChangeLog:
* fold-const.cc (combine_comparisons): Allow eq to combine
with || and ne combine with && if the original rcode was trapping
and the new code is trapping.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/fp-trapping-cmp-1.c: New test.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Patrick Palka [Sat, 25 Jul 2026 20:12:19 +0000 (16:12 -0400)]
c++: function NTTP argument in pack considered unused [PR126280]
This is just the pack version of PR c++/105848, in which our non-dependent
call pruning may cause us to not mark an otherwise unused function pointer
template argument within a pack as used.
PR c++/126280
gcc/cp/ChangeLog:
* pt.cc (mark_template_arguments_used): Split out loop into ...
(mark_template_arguments_used_1): ... here. Recurse into
argument packs.
Patrick Palka [Sat, 25 Jul 2026 20:12:13 +0000 (16:12 -0400)]
libstdc++: Optimize flat_map range insertion for pair-like elements
When inserting a range of pair-like elements we can avoid constructing a
value_type (i.e. pair) temporary and instead obtain the corresponding key
and value directly from *__first.
This came up when looking at LWG 4499 for flat_set::insert_range (which
I think we already optimally implement) but it prompted me to look at
flat_map::insert_range during which I noticed this extra std::move.
libstdc++-v3/ChangeLog:
* include/std/flat_map (flat_map::_M_insert): Avoid constructing
value_type temporary when the iterator already has pair-like
elements.
* testsuite/23_containers/flat_map/1.cc (test14): New test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Jakub Jelinek [Sat, 25 Jul 2026 19:56:48 +0000 (21:56 +0200)]
Use HOST_SIZE_T_PRINT_UNSIGNED in a few other spots
On Thu, Jul 23, 2026 at 12:06 PM John David Anglin <dave.anglin@bell.net> wrote:
> Not all hosts support the "z" format length modifier. Noticed
> by inspection.
That is not the only spot that does this though.
I've grepped for printf.*%z and found this.
2026-07-25 Jakub Jelinek <jakub@redhat.com>
gcc/
* sym-exec/sym-exec-expression.cc (symbolic_bit::print): Use
HOST_SIZE_T_PRINT_UNSIGNED instead of "%zu" and add cast to
fmt_size_t.
* genoutput.cc (main): Likewise.
gcc/cobol/
* symbols.cc (symbols_dump): Use HOST_SIZE_T_PRINT_UNSIGNED instead
of "%zu" and add cast to fmt_size_t.
Reviewed-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
This patch introduces __negdi2_r10 to lib1funcs.S and tidies
some 64-bit negations.
libgcc/
* config/avr/t-avr (FUNCS_notiny): Add _negdi2_r10.
* config/avr/lib1funcs.S (__negdi2_r10): New function.
(__divdi3_moddi3): Use it.
* config/avr/lib1funcs-fixed.S (__mulQ64_work): Use it.
ifcvt: Keep only reaching definitions when rewiring sets [PR126184]
init_noce_multiple_sets_info records earlier SET destinations that are
mentioned by a later SET source. When a pseudo is set more than once, only
its most recent prior definition reaches that source.
Recording every definition is unsafe in the second
noce_convert_multiple_sets_1 attempt. The newest definition can be emitted
directly into its target pseudo, making its replacement a no-op. A later
replacement using an older definition then substitutes a stale value.
PR126184 contains the following dependency chain:
c = x + 1;
x = c * y;
c = z + 3;
y = c * x;
The unfixed conversion computes the last multiply with the temporary that
holds `x + 1`, rather than the reaching `z + 3` value.
The unfixed final sequence forms `x + 1` in x0 and later uses x0 as the
multiply operand:
add x0, x1, 1
csel x1, x1, x3, eq
mul x0, x1, x0
With the fix, x3 retains z until `z + 3` is formed and used by the multiply:
add x3, x3, 3
csel x0, x0, x1, ne
mul x3, x0, x3
Walk definitions from newest to oldest and record only the first match for
each pseudo. Add an AArch64 execution test for the reported dependency.
Bootstrapped and tested on aarch64-none-linux-gnu and
x86_64-pc-linux-gnu.
gcc/ChangeLog:
PR rtl-optimization/126184
* ifcvt.cc (init_noce_multiple_sets_info): Record only the most
recent prior definition of each pseudo register.
gcc/testsuite/ChangeLog:
PR rtl-optimization/126184
* gcc.target/aarch64/pr126184.c: New test.
ifcvt: Reject hard-register destinations in multiple sets [PR126184]
noce_convert_multiple_sets keys its dependency information by destination
register number. Hard registers can have overlapping definitions in
different modes. An exact RTL replacement cannot represent the value from a
partial or mode-changing definition.
Reject hard-register destinations in the block eligibility check. Assert
the resulting pseudo-only invariant when dependency information is
initialized.
Add an RTL execution test with mixed-mode hard-register definitions. It
verifies that the block remains unconverted.
Bootstrapped and regtested on aarch64-none-linux-gnu and
x86_64-pc-linux-gnu.
gcc/ChangeLog:
PR rtl-optimization/126184
* ifcvt.cc (init_noce_multiple_sets_info): Assert that destinations
are pseudos.
(bb_ok_for_noce_convert_multiple_sets): Reject hard-register
destinations.
gcc/testsuite/ChangeLog:
PR rtl-optimization/126184
* gcc.target/aarch64/pr126184-2.c: New test.