Robin Dapp [Tue, 4 Aug 2026 09:37:33 +0000 (11:37 +0200)]
RISC-V: Fix single-step expansion [PR126550].
In expand_const_vector_single_step_npatterns, we use a second vector
builder that is derived from the main one, in order to create a
different alternating pattern for constant synthesis. We later use the
second builder's number of patterns for creating an intermediate
operation. The second builder can have a different number of patterns
than the first one, however, for example when its "global" pattern is
simpler.
This patch uses npatterns from the original builder.
PR target/126550
gcc/ChangeLog:
* config/riscv/riscv-v.cc (expand_const_vector_single_step_npatterns):
User global builder's npatterns.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/pr126550-2.c: New test.
* gcc.target/riscv/rvv/autovec/pr126550.c: New test.
Roger Sayle [Tue, 4 Aug 2026 20:03:20 +0000 (21:03 +0100)]
PR tree-optimization/126242: Check range is defined to avoid ICE.
Here's the latest revision of my patch to resolve PR 126242 (and 126325),
incorporating Richard Biener's feedback to simplify the logic, eliminating
itype_ok and always using calling gimple_match_range_of_expr. This
version also resolves PR tree-optimization/126325 introduced/exposed
by the same change, checking that when transforming (float)x < C into
x < (int)C that (int)C is exactly representable, i.e. that
(float)(int)C == C.
This patch resolves PR tree-opt/126242, an unanticipated interaction
between the two recent (float)i == 1.0 patches to match.pd. The issue
is that value range information is getting queried in circumstances
(on paths) where we've failed to initialize the range and/or ranger
has failed to bound the value. The correction below fixes this in
two ways: initialize the range information in more cases, and check
that the range has been successfully initialized before using it.
The motivation/benefit for the first approach is seen in the example:
unsigned char t = x & 63;
return (float)t > 100.0;
Previously, because unsigned char can be safely represented in a
float we'd use the bounds [0,255], and transform this to t > 100.
Obviously, there's benefit in using ranger to reduce the range to
[0,63], even when the integer type fits the floating point type,
allowing the above expression to be simplified even further to false.
2026-08-04 Roger Sayle <roger@nextmovesoftware.com>
Richard Biener <rguenther@suse.de>
gcc/ChangeLog
PR tree-optimization/126242
PR tree-optimization/126325
* match.pd ((FTYPE) N CMP CST): Always attempt to initialize
value range information. Check undefined_p before using range
bounds. Check that icst_val hasn't overflowed, i.e. that
(FTYPE)ICST == CST, before transforming to integer comparison.
gcc/testsuite/ChangeLog
PR tree-optimization/126242
PR tree-optimization/126325
* gcc.dg/pr126325.c: New test case.
* gfortran.dg/pr126242.f90: New reduced test case.
* gfortran.dg/pr41928-2.f90: Also compile pr41928.f90 with -Ofast.
Jakub Jelinek [Tue, 4 Aug 2026 19:42:49 +0000 (21:42 +0200)]
testsuite: Fix up gcc.dg/pr126464.c test [PR126464]
On Tue, Aug 04, 2026 at 02:13:19PM +0200, Torbjorn SVENSSON wrote:
> This causes regression on most (all?) arm-none-eabi targets.
> /build/gcc_src/gcc/testsuite/gcc.dg/pr126464.c:56:3: warning: floating constant exceeds range of 'long double' [-Woverflow]
This patch guards it with preprocessor tests whether such floating point
constants are representable.
2026-08-04 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/126464
* gcc.dg/pr126464.c: Guard uses of 1e300 with
__DBL_MAX_10_EXP__ >= 301 and uses of 1e4000L with
__LDBL_MAX_10_EXP__ >= 4001.
Reviewed-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Jakub Jelinek [Tue, 4 Aug 2026 19:41:16 +0000 (21:41 +0200)]
testsuite: Fix up gcc.dg/torture/bitint-100.c test [PR124948]
On Mon, Aug 03, 2026 at 01:56:35PM +0200, Torbjorn SVENSSON wrote:
> On 2026-08-03 13:54, Jakub Jelinek wrote:
> > On Mon, Aug 03, 2026 at 01:50:18PM +0200, Torbjorn SVENSSON wrote:
> > > This change introduces new failures for arm-none-eabi using thumb/arch=armv6s-m/cpu=cortex-m0/float-abi=soft/fpu=auto.
> > >
> > > bitint-100.c:(.text+0x5a): undefined reference to `__atomic_compare_exchange_4'
> > > /build/install-native/arm-none-eabi/bin/ld: (__atomic_compare_exchange_4): Unknown destination type (ARM/Thumb) in /tmp/ccgSaSgH.o
> > > FAIL: gcc.dg/torture/bitint-100.c -O0 (test for excess errors)
> > >
> > > Same failure exist on both trunk and releases/gcc-16.
> >
> > I thought gcc has been changed to add -latomic_asneeded by default.
> > Or is this because the linker doesn't support it in this configuration?
> To my knowledge, there is no atomic support for armv6s-m, but I can be wrong.
Most of the tests that are dg-do run and use atomics on int/long use
sync_int_long effective target. Atomics on _BitInt(17), i.e. something
on all currently supported targets larger than short, probably need to be
treated the same.
2026-08-04 Jakub Jelinek <jakub@redhat.com>
PR target/124948
* gcc.dg/torture/bitint-100.c: Require also sync_int_long effective
target.
Reviewed-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Jakub Jelinek [Tue, 4 Aug 2026 19:38:08 +0000 (21:38 +0200)]
cobol: Unbreak bootstrap
Cobol FE uses -Werror=format-diag during bootstrap, so bootstrap
is currently broken since the recent parse.y change:
../../gcc/cobol/parse.y:2188:43: error: unquoted option name '-dialect' in format [-Werror=format-diag]
The following patch fixes that, similarly to other spots that diagnose
-dialect ibm.
2026-08-04 Jakub Jelinek <jakub@redhat.com>
* parse.y (selected_name): Use %<-dialect ibm%> instead of just
-dialect ibm.
The stage 2 and stage 3 object comparison runs one command per object in a
serial shell loop. Everything after it waits while an otherwise idle machine
compares thousands of objects.
Generate one make target per object and run the comparisons through $(MAKE),
so they share the original jobserver. Keep the generated makefile and result
shards invocation-specific, clean them on normal and signal exits, and sort
the shards before creating the traditional .bad_compare diagnostic. Files in
the exclusion list still only warn. Comparator statuses other than zero or
one now report an operational error instead of being treated as equal.
The tail-based fallback for cmp implementations without byte skipping used
fixed temporary names. Give those files process-specific names, clean them
with a trap, and preserve the same status contract for tail failures and
signals.
On highly parallel AArch64 and x86_64 systems this reduces comparison wall
time by about 95%.
ChangeLog:
* Makefile.tpl ([+compare-target+]): Run object comparisons through an
invocation-specific parallel sub-make. Collect sorted failure shards
and clean temporary state on exit.
* Makefile.in: Regenerate.
* configure: Regenerate.
config/ChangeLog:
* acx.m4 (ACX_PROG_CMP_IGNORE_INITIAL): Use process-specific temporary
files and clean them on exit. Diagnose tail failures as errors.
But that MEM is a TARGET_MEM_REF which is not supported by
factor_out_conditional_load yet. This adds simple TARGET_MEM_REF
support by requiring the index/step and index2 to be all the same.
It even supports a mismatched TARGET_MEM_REF with a MEM_REF but
only if the TARGET_MEM_REF had an null index/step and index2.
We now get a similar code generation for telecom/viterb00data_1 (EEMBC)
at -O2 as LLVM.
Changes since v1:
* v2: Fix small issue checking of equality and nullptr of TARGET_MEM_REF
operands.
* v3: Fix operand_equal check.
* v4: Add safe_operand_equal. Also use TMR_* instead of TREE_OPERAND.
Bootstrapped and tested on x86_64-linux-gnu.
PR tree-optimization/100173
gcc/ChangeLog:
* fold-const.h (safe_operand_equal_p): New function.
* tree-ssa-phiopt.cc (factor_out_conditional_load): Add simple
support for TARGET_MEM_REF.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/factor_op_phi-load-target_mem-1.c: New test.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Portable code computing a 2N-bit product on an N-bit target splits the
operands into N/2-bit halves, forms four partial products, and
propagates the carries by hand. Fold that longhand back to a widening
multiply plus shift for the high part and a MULT_EXPR for the low part:
match.pd atoms match the partial-product and carry shapes (including the
PHI<base + pow2, base> carry form); forwprop linearizes the outer
add/ior chain into a multiset of summands, looks it up in
long_mul_table, and gates the rewrite on cross-summand consistency (one
operand pair, N/2-bit shifts, hilo cross-half products) and a per-row
extra check. Twelve rows cover six high-part and six low-part carry
shapes. Emit (N)(((2N) op1 * (2N) op2) >> N), which
pass_optimize_widening_mul lowers to WIDEN_MULT_EXPR or
MULT_HIGHPART_EXPR; where 2N is unsupported (e.g. OImode for 128x128),
lower_long_mul_high_chain resynthesizes the longhand at N precision so
2N is never materialized.
750.sealcrypto_r: +25% on AArch64 Neoverse-N1, +59% on x86-64 Zen4.
Compile-time impact ~0.1% on gcc/*.cc, confined to forwprop.
Bootstrapped and regression-tested (before squash) on AArch64,
x86-64, ARM and PowerPC.
PR tree-optimization/107090
gcc/ChangeLog:
* match.pd: Add atom match recognizers for long-multiply
(mul_hi, mul_lo, mul_hilo, mul_lolo, mul_hihi, mul_cross_sum,
mul_low_sum, mul_low_accum, mul_carry_cross_sum,
mul_carry_low_sum, mul_carry_low, mul_ladder_sum1,
mul_ladder_sum2, mul_ladder_sum3, mul_ladder_part_sum), the
cond_carry_add and cond_carry_add_neg recognizers for the 2-arg
PHI carry form, one per gcond polarity, and long_mul_high_chain
for the emitted chain shape.
* tree-ssa-forwprop.cc (gimple_cond_carry_add): Declare.
(gimple_cond_carry_add_neg): Likewise.
(gimple_mul_hi): Likewise.
(gimple_mul_lo): Likewise.
(gimple_mul_hilo): Likewise.
(gimple_mul_lolo): Likewise.
(gimple_mul_hihi): Likewise.
(gimple_mul_cross_sum): Likewise.
(gimple_mul_low_sum): Likewise.
(gimple_mul_low_accum): Likewise.
(gimple_mul_carry_cross_sum): Likewise.
(gimple_mul_carry_low_sum): Likewise.
(gimple_mul_carry_low): Likewise.
(gimple_mul_ladder_sum1): Likewise.
(gimple_mul_ladder_sum2): Likewise.
(gimple_mul_ladder_sum3): Likewise.
(gimple_mul_ladder_part_sum): Likewise.
(build_mul_high_seq): New, emits (N)(((2N) op1 * (2N) op2) >> N)
into a caller-supplied destination.
(long_mul_apply_extras): New, combines the preserved addends back
on top of the folded multiply.
(create_mul_high_seq): New, replaces the statement with the
high-part multiply plus any extras.
(create_mul_low_seq): New, likewise for the low part.
(enum long_mul_kind): New.
(enum long_mul_extract): New.
(struct long_mul_summand): New.
(long_mul_linearize_chain): New, walks the outer add/ior chain
into a multiset of leaves.
(long_mul_is_lshift_def): New.
(long_mul_set_summand): New.
(long_mul_classify_carry): New, most-specific carry atom first.
(long_mul_classify_plus_kinds): New, likewise by specificity.
(long_mul_classify_hi_extract): New.
(long_mul_classify_lo_extract): New.
(long_mul_classify_shl_extract): New.
(long_mul_classify_bare): New.
(long_mul_classify_summand): New, classify a summand via the
match.pd atoms.
(long_mul_summand_compare): New.
(struct long_mul_row): New.
(long_mul_same_ops): New.
(long_mul_is_cross_half): New.
(long_mul_hilo_orientation): New, orientation of a mul_hilo
capture relative to (op0, op1).
(long_mul_canonical_ops): New.
(long_mul_find_summand): New.
(long_mul_check_consistency): New, cross-summand consistency
check (operand pairing, half-width shifts, hilo cross-half).
(long_mul_signature_matches): New.
(long_mul_check_two_carries): New extra check, validates the
two-carry row's carry operands against the canonical (op0, op1).
(long_mul_check_low_plus_defer): New extra check, defers the
low-plus row while a GT/LT/GE/LE use shares an operand with the
PLUS.
(long_mul_hint_shared_intermediate): New, dump-file hint pointing
at a shared inner addition.
(long_mul_classify_match): New, looks a summand multiset up in
long_mul_table, runs the per-row checks, and gates the high-part
emit on optimize_widening_mul_active_p.
(long_mul_classify_chain): New, linearize plus classify plus
table lookup; sets aside leaves that classify as no summand and
takes an optional pre-classified summand.
(match_long_mul): New, top-level entry: starts only at a chain
end and dispatches to create_mul_high_seq / create_mul_low_seq
with any preserved addends.
(match_long_mul_phi): New PHI-driven entry, recognizes a
cond_carry_add(_neg) PHI and folds the long-multiply shape when
the rest of the high-part chain matches.
(pass_forwprop::execute): Call match_long_mul on PLUS_EXPR and
BIT_IOR_EXPR statements, and match_long_mul_phi on each PHI in
the degenerate-PHI walk.
* tree-ssa-math-opts.cc (can_widen_to_narrow_p): New.
(build_long_mul_partials): New, emits the four partial products
using widening or plain multiplies.
(emit_long_mul_highpart): New, the high N bits of an N-bit
product, as a longhand over (N/2)-bit partials.
(combine_long_mul_halves): New, the high N bits of a product of
two 2N-bit values given as N-bit halves.
(long_mul_op_fits_p): New, true when an operand is provably
representable in narrow_prec unsigned bits.
(long_mul_split_operand): New, splits an operand into N-bit
halves using only N-bit operations.
(long_mul_only_low_half_used_p): New.
(narrow_long_mul_low_half): New, narrow a 2N low-half-only mult
the target cannot expand to an N-bit mult.
(narrow_long_mul_operands): New, recurse into chained wide
products after a narrowing/lowering.
(gimple_long_mul_high_chain): Declare.
(lower_long_mul_high_chain): New, lowers the high-part chain to a
longhand at narrow precision, splitting each operand into N-bit
halves and combining them, then narrowing or dropping the
residual 2N mult via the helpers.
(optimize_widening_mul_active_p): New, shared gate used by
pass_optimize_widening_mul::gate and by the forwprop long-multiply
recognizer. Return false when optimize_debug.
(math_opts_dom_walker::after_dom_children): Dispatch to
lower_long_mul_high_chain on the outer convert. Run
narrow_long_mul_low_half on MULT_EXPR before the widen/fma
conversion attempts.
* tree-ssa-math-opts.h (optimize_widening_mul_active_p): Declare.
gcc/testsuite/ChangeLog:
* lib/target-supports.exp: Add check_effective_target_oi_mode,
which enumerates targets whose mode table declares OImode.
* gcc.dg/long-mul-128-Og.c: New test.
* gcc.dg/torture/long-mul-128.c: New test.
* gcc.dg/torture/long-mul-64-run.c: New test.
* gcc.dg/tree-ssa/long-mul-boundary-64.c: New test.
* gcc.dg/tree-ssa/long-mul-boundary.c: New test.
* gcc.dg/tree-ssa/long-mul-carry.c: New test.
* gcc.dg/tree-ssa/long-mul-chain-cse-128.c: New test.
* gcc.dg/tree-ssa/long-mul-chain-trunc-128.c: New test.
* gcc.dg/tree-ssa/long-mul-extra-addend.c: New test.
* gcc.dg/tree-ssa/long-mul-ladder.c: New test.
* gcc.dg/tree-ssa/long-mul-low-plus.c: New test.
* gcc.dg/tree-ssa/long-mul-partial.c: New test.
* gcc.dg/tree-ssa/long-mul-two-carry.c: New test.
* gcc.target/aarch64/long_mul.c: New test.
* gcc.target/arm/long-mul-thumb1-inline.c: New test.
* gcc.target/arm/long-mul-umull.c: New test.
* gcc.target/i386/long_mul.c: New test.
* gcc.target/i386/widen_mult_high_chain.c: New test.
Co-authored-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
Only the low bits of the addition survive the first mask, so the constant
moves to the other side of the comparison and the addition goes away. A
comparison constant that does not fit the mask makes the result fixed.
Clearing the low bits rounds the value down, and a rounded value passes a
relational comparison exactly when the value itself passes it against the
constant with those bits set, so the second mask goes away too. The
other two predicates are already canonicalised into these.
int f (int x) { return (x & -8) > 16; }
aarch64 -O2:
before after
and w0, w0, -8 cmp w0, 23
cmp w0, 16 cset w0, gt
cset w0, gt
Two existing tests observe shapes this rewrite now folds. bic-bitmask-19.c
scans for "> 1" and the loop guard (n & -16) > 0 becomes n > 15, which the
regex also matches, so it is anchored on the statement end. pr68217.c
relies on the comparison keeping the masked value live, so the value is
returned instead.
Keep signed additions that trap or carry sanitizer instrumentation.
Also accept high-mask constants whose discarded low bits are already set.
Bootstrapped and tested on aarch64-none-linux-gnu.
* gcc.dg/tree-ssa/maskcmp-1.c: New test.
* gcc.dg/bic-bitmask-19.c: Anchor the comparison scan.
* gcc.dg/pr68217.c: Return the masked value.
* gcc.dg/tree-ssa/maskcmp-overflow-1.c: New test.
* gcc.dg/tree-ssa/maskcmp-overflow-2.c: New test.
Tamar Christina [Tue, 4 Aug 2026 14:35:26 +0000 (15:35 +0100)]
vect: when REALPART/IMAGPART also check their def stmts [PR126593]
The check in compatible_complex_nodes_p is a bit too loose in that we assumed
that when we see a REAL/IMAG pair of statement in a TWO_OPERANDS they must have
come from the same defining statement.
This is of course too loose and the operands should be checked explicitly.
gcc/ChangeLog:
PR tree-optimization/126593
* tree-vect-slp-patterns.cc (compatible_complex_nodes_p): Check def
stmts of real and imag pairs.
gcc/testsuite/ChangeLog:
PR tree-optimization/126593
* gcc.target/aarch64/pr126593.c: New test.
Warped BB rotation due to the incorrect profiles aside (different problem)
this loop will exit one iteration early since the IV check (d < a) is checked
as (++d < a).
This means that when branched to the scalar code we do 2 vector iterations in
the worst case rather than 1.
This is due to the fact that the loop is essentially a do-while loop coming into
the vectorizer. We detect this loop as a LOOP_VINFO_EARLY_BREAKS_VECT_PEELED
because it's the same form as a normal while-do loop but where we picked a
different exit than the loop latch exit.
Because of the versioning and other checks in the preheader we know that if you
reach the loop body you'll always do at least 1 iteration of the body (but
possibly never the latch). i.e. the d != 0 check is always true should you get
to the end of the pre-header.
The codegen reflects this but because of the early IV exit check we never get to
the body.
Alfie's patch to fix this changed the `d++ < a` check to the correct (d < a)
check, but due to how the control flow becomes we end up doing
mask_1 = PHI <mask_0, next_mask>
if (mask_1)
and causes us to retest the mask, even though the mask generation which happens
in the pre-header has guaranteed that for the first iteration it's non-empty.
So we lose information because the check in the header is used by both the value
from the pre-header and the latch on loop back.
Instead of doing that this patch just changed the control flow to reflect that
we can always execute the body at least once. In effect it moves the IV latch
check to the end.
PR tree-optimization/126301
* tree-vect-loop-manip.cc (vect_use_loop_latch_condition_p): New.
(vect_set_loop_condition_partial_vectors, vect_set_loop_condition): Use
it to rewrite latch and condition.
(vect_set_loop_controls_directly): Adjust IV for do-loop conversion.
gcc/testsuite/ChangeLog:
PR tree-optimization/126301
* gcc.target/aarch64/sve/peeled.c: New test.
* gcc.target/aarch64/sve/peeled1.c: New test.
* gcc.target/aarch64/sve/peeled1_run.c: New test.
* gcc.target/aarch64/sve/peeled2.c: New test.
* gcc.target/aarch64/sve/peeled2_run.c: New test.
* gcc.target/aarch64/sve/peeled_run.c: New test.
Tamar Christina [Tue, 4 Aug 2026 14:27:12 +0000 (15:27 +0100)]
vect: simplify is_linear_load_p using vec_perm_builder and reject invalid [PR126592]
is_linear_load_p is supposed to test for valid permutations of lanes of complex
arithmetic. It was written as a manual loop that iteratively discredited
what a permutation could be and returned the permute.
However the code is a bit hard to prove correct and as PR1265992 points out it
accepts at least one invalid permute [0 2 2 2].
To fix this and simplify the code to prevent other issues I have rewritten it to
use vec_perm_indices and use the convenient helper series_p ();
gcc/ChangeLog:
PR tree-optimization/126592
* tree-vect-slp-patterns.cc (is_linear_load_p): Rewrite using
vec_perm_indices.
gcc/testsuite/ChangeLog:
PR tree-optimization/126592
* gcc.target/aarch64/pr126592.c: New test.
Tamar Christina [Tue, 4 Aug 2026 14:25:54 +0000 (15:25 +0100)]
AArch64: block COMPLEX_MUL when honoring signed zeros [PR126589]
as PR126589 points out on AArch64 we emulate COMPLEX_MUL using COMPLEX_FMA by
seeding the accumulator with +0.0. However depending on the rounding/flushing
behavior we can end up with the wrong sign on the zero result.
There's no real performant way to fix this (though I wonder if a BSL to copy
the sign bits would be faster) so this adds !HONOR_SIGNED_ZEROS as a requirement
for AArch64's expanders for cmul.
gcc/ChangeLog:
PR target/126589
* config/aarch64/aarch64-simd.md (cmul<conj_op><mode>3): Require not
honor signed zeros.
* config/aarch64/aarch64-sve.md (cmul<conj_op><mode>3): Require not
honor signed zeros.
gcc/testsuite/ChangeLog:
PR target/126589
* gcc.target/aarch64/sve/complex_mul_1.c: Add -fno-signed-zeros.
* gfortran.target/aarch64/pr122408_1.f90: Likewise.
* gcc.target/aarch64/pr126589.c: New test.
* gcc.target/aarch64/sve/pr126589.c: New test.
Tamar Christina [Tue, 4 Aug 2026 14:24:53 +0000 (15:24 +0100)]
vect: try all 8 multiplication orderings for complex patterns [PR126589]
PR126589 make COMPLEX_MUL require -fno-signed-zeros for AArch64, but when using
this we miss many of the complex matching. This is because we get a different
order of the operands for multiplication.
We normally try just flipping the two multiplies around but not their operands.
This patch changes it to try all 8 variants. Note that they still have to pass
compatible_complex_nodes_p and df analysis in linear_loads_p so we won't accept
invalid combinations.
There are no tests for this but it prevents patch 2 from introducing failures.
gcc/ChangeLog:
PR target/126589
* tree-vect-slp-patterns.cc (vect_validate_multiplication): Refactor.
(vect_validate_multiplication_commutative): New.
(complex_mul_pattern::matches, complex_fms_pattern::matches): Use it.
Tamar Christina [Tue, 4 Aug 2026 14:23:23 +0000 (15:23 +0100)]
middle-end: fix condition on multiple negate pattern [PR126602]
The optimization added in r17-527-gca2920882be has a bogus constraint which
allows floating point FMAs through and folds them into integer ones. i.e. we
produce
Karl Meakin [Wed, 10 Dec 2025 16:21:55 +0000 (16:21 +0000)]
aarch64: use `unspec` type for unspec codes
Change the type of variables/parameters/data members that are used to hold
unspec codes from `int` to `unspec`. This makes GDB print their symbolic names
rather than their integer value.
Karl Meakin [Tue, 16 Sep 2025 17:30:11 +0000 (17:30 +0000)]
aarch64: Use variadic arguments
When defining various index enums (eg `vector_type_index`,
`mode_suffix_index`) we are only interested in the name (the first
argument). So all the other arguments to the `DEF_` macro can be ignored
by using `...`.
Karl Meakin [Tue, 16 Sep 2025 17:27:54 +0000 (17:27 +0000)]
aarch64: Define `DEF_SVE_TYPE_SUFFIX` in terms of `DEF_SVE_NEON_TYPE_SUFFIX`
Define `DEF_SVE_TYPE_SUFFIX` in terms of `DEF_SVE_NEON_TYPE_SUFFIX` so
callers only need to define `DEF_SVE_NEON_TYPE_SUFFIX` when including
`aarch64-sve-builtins.def`.
gcc/ChangeLog:
* config/aarch64/aarch64-sve-builtins.def (DEF_SVE_TYPE_SUFFIX): Define
in terms of `DEF_SVE_NEON_TYPE_SUFFIX`.
* config/aarch64/aarch64-acle-builtins.cc (DEF_SVE_TYPE_SUFFIX): Delete
since it is now defined in terms of `DEF_SVE_NEON_TYPE_SUFFIX`.
(DEF_SVE_NEON_TYPE_SUFFIX): Move to be next to `DEF_SVE_TYPE_SUFFIX`.
* config/aarch64/aarch64-acle-builtins.h (DEF_SVE_TYPE_SUFFIX): Rename to ...
(DEF_SVE_NEON_TYPE_SUFFIX): ... here.
Tamar Christina [Tue, 4 Aug 2026 14:21:54 +0000 (15:21 +0100)]
vect: move check for safe speculative reads for inbound access [PR126369]
It turns out that the DR_SCALAR_KNOWN_BOUNDS check which checks to see that even
if misaligned but all scalar accesses are in bounds of a known fixed size array
then we're OK and just need to force masking.
The loop it was placed in would exit early after the first misaligned access and
so when you have more than one data access in the loop it wouldn't mark the
other accesses as safe to speculate.
---
Changes in v5:
- Drop -O0 from both tests and add a return value to avoid any potential
DCE issues.
- Move -mbig-endian to dg-additional-options.
- Remove the dg-xfail-if for RVV on big-endian builds.
- Link to v4: https://patchwork.sourceware.org/project/gcc/patch/20260619120406.373933-1-aleksa.paunovic@htecgroup.com/
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_subword_address): Add emit_move_insn for big-endian.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/amo/big-endian-subword-amo-hi.c: New test.
* gcc.target/riscv/amo/big-endian-subword-amo-qi.c: New test.
Shreya Munnangi [Tue, 4 Aug 2026 13:16:37 +0000 (07:16 -0600)]
[RISC-V][PR target/108031] Expose address computations for atomic memory operations
This is a patch from Shreya that takes a step towards fixing pr108031.
Access to objects in static storage requires a high/lo_sum pair on RISC-V.
Often, but not always, the lo_sum expression can be folded into the actual
memory reference. One of the common cases where it can *not* fold in is atomic
memory operations. So if (for example) we access nearby fields in a structure
in static memory we'll often see
lui a5,%hi(s)
li a4,1
addi a5,a5,%lo(s)
amoadd.w a0,a4,0(a5)
lui a5,%hi(s+4) <-- this should be: addi a5, a5, 4
addi a5,a5,%lo(s+4) <-- this should be removed
amoadd.w a3,a4,0(a5)
add a0,a0,a3
We'd like to replace the second lui+addi pair with a single addi. That's
normally a job for CSE, but due to implementation details of the RISC-V atomics
we're failing to even expose those addresses to CSE.
The core issue is the predicates on these instructions are wider than the
constraints and as a result the lo_sum stays folded into the memory reference
until LRA realizes the constraints don't match and the lo_sum part of the
address computation gets reloaded.
The fix is straightforward. Tighten the operand predicates. RISC-V only
allows simple memory indirect operands for these instructions, yet surprisingly
we didn't have a predicate for that kind of address. This patch adds an
appropriate predicate, then uses it on the dozen or so relevant
patterns/expanders.
That's enough to expose the address calculation to CSE, schedulers, etc. In my
(Jeff's) opinion the patch stands as an independent improvement, even though it
doesn't fix 108031. The next (and final) step to fix 108031 will most likely
be a costing model fix. ie, CSE will do the right thing with the addresses are
fully exposed, but it rejects the changes because the RISC-V cost model is
broken.
This has been bootstrapped and regression tested on the c920. K3 bootstrap &
regression test was just about done when a cat went crazy behind my desk and
ultimately dislodged the power cable from the wall. It's restarted, but
results are now 9 hours out :( riscv32-elf and riscv64-elf both worked fine,
of course.
Richard Earnshaw [Wed, 29 Jul 2026 12:18:20 +0000 (13:18 +0100)]
arm: Thumb2 reg preferencing for vfp variant of movsi [PR124043]
This pattern currently masks a lot of alternatives from register
preferencing, but this can cause the register allocator to prefer to
spill and reload from the stack when transferring values between core
and VFP registers. (This is probably exacerbated by LRA also chosing to
disparage such alternatives when doing final register selection.) This
patch is not a complete rework of the preferences, but does try to bring
the alternatives closer to the way we handle registers when compiling in
arm mode (A32).
This pattern needs reworking - it probably hasn't been looked at
properly since we moved to LRA.
gcc/ChangeLog:
PR target/124043
* config/arm/vfp.md (thumb2_movsi_vfp): Don't hide the t->r
alternative from register preferencing.
Richard Earnshaw [Wed, 29 Jul 2026 10:46:40 +0000 (11:46 +0100)]
arm: handle neon vec_dup from select of 128-bit vector
The Neon instruction set lacks a direct vdup from a lane in a 128-bit
vector; but one isn't needed because the lane is a constant and we can
handle the appropriate half of a 128-bit register simply by selecting
that during output.
Additionally, we can also handle core registers as the source operand
for both 64-bit and 128-bit sources without needing to copy the entire
vector to VFP/SIMD regs; at most a simple shift is needed to extract
the appropriate lane to the lower bits of a scratch core reg, but in
some cases we can use the core reg directly (when no shift is needed)
since the upper bits are ignored.
I've also disambiguated the two paterns named
neon_vdup_lane<mode>_internal by inserting the iterator name into the
pattern. This doesn't change anything in terms of generated code, but
makes the pattern names in the MD file unique.
gcc/ChangeLog:
* config/arm/neon.md (neon_vdup_lane<VDQW:mode>_internal):
Handle core registers as the input vector operand by splitting.
(neon_vdup_lane<VHFBF:mode>_internal): Likewise.
(neon_vdupq_lane<VQ2BF:mode>_internal): New pattern.
gcc/testsuite/ChangeLog:
* gcc.target/arm/crypto-vsha1cq_u32.c: Don't expect a vmov.32 in
the generated code.
* gcc.target/arm/crypto-vsha1h_u32.c: Likewise.
* gcc.target/arm/crypto-vsha1mq_u32.c: Likewise.
* gcc.target/arm/crypto-vsha1pq_u32.c: Likewise.
* gcc.target/arm/armv8_2-fp16-neon-1.c: Update expected output.
* gcc.target/arm/armv8_2-fp16-neon-2.c: Likewise.
Egas Ribeiro [Fri, 19 Jun 2026 18:19:51 +0000 (19:19 +0100)]
analyzer: support exception subclass matching [PR analyzer/119697]
The analyzer's exception_matches_type_p only treated an exception as
caught when the handler type and exception type were identical, so a
handler catching a base class did not match a thrown derived class.
Add an exception_matches_type_p langhook returning whether a handler of
one type catches an exception of another per the language's rules. The
default returns false, preserving behavior for frontends without
exception support (such as C). The C++ frontend implements it via
can_convert_eh (now non-static). This keeps the analyzer language
agnostic and the C++ catch-matching rules in the frontend.
PR analyzer/119697
gcc/ChangeLog:
* langhooks.h (struct lang_hooks): Add exception_matches_type_p.
* langhooks-def.h (LANG_HOOKS_EH_MAY_CATCH_P): Define as
hook_bool_tree_tree_false.
(LANG_HOOKS_INITIALIZER): Add it.
gcc/cp/ChangeLog:
* except.cc (can_convert_eh): Make non-static.
* cp-tree.h (can_convert_eh): Declare.
* cp-lang.cc (LANG_HOOKS_EH_MAY_CATCH_P): Define as
can_convert_eh.
gcc/analyzer/ChangeLog:
* ops.cc: Include "langhooks.h".
(exception_matches_type_p): Use the exception_matches_type_p
langhook; fix catch/exception argument order.
gcc/testsuite/ChangeLog:
* g++.dg/analyzer/exception-dynamic-spec.C: Remove xfail.
* g++.dg/analyzer/exception-subclass-1.C: Remove xfail.
__analyzer_dump_path in the catch handler.
* g++.dg/analyzer/exception-subclass-2.C: Add
__analyzer_dump_path in the catch handler;
Add __analyzer_eval to interprocedural call.
* g++.dg/analyzer/exception-subclass-3.C: New test.
* g++.dg/analyzer/exception-subclass-4.C: New test.
* g++.dg/analyzer/multiple-inheritance-1.C: New test.
Jakub Jelinek [Tue, 4 Aug 2026 08:37:09 +0000 (10:37 +0200)]
widening_mul: Fix up ICE in maybe_optimize_guarding_check [PR126601]
The following testcase ICEs, because we try to quick_push into an already
full vector.
The caller (match_arith_overflow) has
auto_vec<gimple *, 8> mul_stmts;
and 0-6 mul_stmts.quick_push (...); calls (none of that in a loop), and then
call to that maybe_optimize_guarding_check function which does one
quick_push, but the function is called in a
FOR_EACH_IMM_USE_STMT (use_stmt, iter, cast_lhs ? cast_lhs : lhs)
loop, so if we are unlucky as on the attached testcase, it is called more
than twice and either triggers ICE, or worse with checking disabled buffer
overflow.
The following patch fixes that by using safe_push in that spot instead.
2026-08-04 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/126601
* tree-ssa-math-opts.cc (maybe_optimize_guarding_check): Use safe_push
on mul_stmts rather than quick_push.
<bb 6> [local count: 1073741824]: // phi_bb
# SR.27_4 = PHI <0(2), -1(3), 1(4), -128(5)>
_2 = SR.27_4 > 0;
to a single comparison (i.e. say (a <=> b) > 0 in C++) (it handles
also just 2 comparisons instead of 3, but this bug is about the 3
comparisons).
In
if (e1->flags & EDGE_TRUE_VALUE)
{
if (tree_to_shwi (arg0) != -128
|| absu_hwi (tree_to_shwi (arg1)) != 1
|| wi::to_widest (arg1) == wi::to_widest (arg2))
return false;
}
else if (tree_to_shwi (arg1) != -128
|| absu_hwi (tree_to_shwi (arg0)) != 1
|| wi::to_widest (arg0) == wi::to_widest (arg2))
return false;
(where e1 is 4->6 edge above, arg0 is -128(5), arg1 is 1(4),
arg2 is -1(3), cond2_phi_edge is 3->6 edge above) we deal with
the different cases of whether the TRUE edge goes directly to
phi_bb or through the empty middle_bb in between.
Right above the above checks is
if ((cond2_phi_edge->flags & EDGE_FALSE_VALUE)
&& HONOR_NANS (TREE_TYPE (lhs1)))
return false;
so for HONOR_NANS, cond2_phi_edge must be TRUE edge, otherwise
it can be either. The problematic check that causes the miscompilation
of the testcase below wants to verify that the two comparisons
(cmp1 being code of a_3(D) > b_5(D) and cmp2 a_3(D) < b_5(D)))
are actually different, not just non-removed useless duplications
(which is what causes miscompilation of the testcase below).
The lhs2 == lhs1 xored case is whether the 2 comparisons are
x cmp1 y vs. x cmp2 y or x cmp1 y vs. y cmp2 x (earlier code verifies
the operands aren't different in other way with the exception of
integral comparisons and < 4 vs. <= 3 etc.).
For the HONOR_NANS case where we know cond2_phi_edge is TRUE
the other xor operand is whether both cmp2 and cmp1 are </<= or
>/>= (note, we can treat LT_EXPR and LE_EXPR the same because
the optimization requires an equality comparison first, so
LT_EXPR vs. LE_EXPR doesn't matter). But for !HONOR_NANS I wrote
a condition checking both the comparison codes and corresponding
edge flags. That is wrong because whether e1 is TRUE or FALSE
edge has been accounted already in the if (e1->flags & EDGE_TRUE_VALUE)
code above, all we care about is whether cond2_phi_edge is EDGE_TRUE_VALUE
or EDGE_FALSE_VALUE or the comparison codes of the two comparisons
(and order of their arguments).
So, instead this xors lhs2 == lhs1 with whether cmp{1,2} are the same
with whether cond2_phi_edge is EDGE_FALSE_VALUE.
For HONOR_NANS there is no difference because the last term will be false.
The pr94589*.c tests already cover quite a lot of different cases that
should or shouldn't be matched.
For 15 and older the testcase will need to be tweaked slightly (see the PR),
so that it tests miscompilation in those releases.
2026-08-04 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/126564
* tree-ssa-phiopt.cc (spaceship_replacement): Fix up condition
when to punt because of redundant cmp1 with cmp2, xor in
lhs1 == lhs2 with difference of cmp2 from cmp1 (ignoring
LT_EXPR vs. LE_EXPR and GT_EXPR vs. GE_EXPR differences) and
1 if cond2_phi_edge is EDGE_FALSE_VALUE.
For integer to floating conversions I've added frange_drop_infs
call into the handler. Supposedly I thought that integers converted
to floating point are never +-inf, but that is clearly not the case
as the testcases show. For _Float16 it can be +-inf very easily,
as the finite range is just [-65504.0f16,65504.0f16], for others
all one needs is a large enough _BitInt.
The following patch just drops that call. In the common cases,
+-inf will not appear in the range anyway, lb and ub will be usually
finite.
aarch64: Add missing CC clobber to max/min-of-add/sub patterns [PR116815]
*aarch64_plus_within_<optab><mode>3_<ovf_commutate> and
*aarch64_minus_within_<optab><mode>3 split into a flag-setting ADDS or SUBS
followed by a CSEL, but their insn patterns do not say that they write the
condition codes.
For
unsigned f (unsigned a, unsigned b, unsigned c, unsigned d)
{
unsigned s = a + b;
unsigned m = s > a ? s : a;
return (c < d && a < b) ? m : d;
}
which claims to leave the flags alone. The compare feeding the enclosing
CCMP chain is therefore treated as still live and is removed, and split1
then emits an ADDS that overwrites the flags the outer CSEL reads:
adds w1, w0, w1
csel w1, w1, w0, cc
csel w0, w1, w3, cc
so f (5, 7, 9, 2) returns 12 rather than 2.
Add the (clobber (reg:CC CC_REGNUM)) that the neighbouring
*aarch64_minmax_plus pattern already carries. The comparison is then kept:
cmp w2, w3
ccmp w0, w1, 2, cc
bcs .L2
adds w1, w0, w1
csel w3, w1, w0, cc
Bootstrapped and tested on aarch64-none-linux-gnu.
gcc/ChangeLog:
PR middle-end/116815
* config/aarch64/aarch64.md
(*aarch64_plus_within_<optab><mode>3_<ovf_commutate>): Add a
clobber of CC_REGNUM.
(*aarch64_minus_within_<optab><mode>3): Likewise.
gcc/testsuite/ChangeLog:
PR middle-end/116815
* gcc.target/aarch64/pr116815-4.c: New test.
sched-deps: record barriers once instead of per register
Before reload, sched_analyze_insn records each barrier in every reg_last
entry. The next barrier can add the same dependence once per register.
Without the dependency cache, each addition linearly searches the
dependence list. This can make barrier analysis quadratic in function size.
For non-selective scheduling before reload, record barriers once in a
pending list. Treat it as the logical sets list for untouched registers
and materialize it when a register is first touched. Emit its dependence
at the first gap in the ascending register walk to preserve eager order.
Reconcile dirty-only entries and combine pending and materialized state in
deps_join. Keep the eager form after reload and for selective scheduling.
Target-neutral RTL selftests cover full and sparse register bitmaps and all
state combinations. They check stale-dependence removal and producer
order.
On an aarch64 system, compiling gimple-match-6 is 47.5% faster at -O3.
Generated assembly is unchanged.
I've also confirmed that in all of SPEC2026 the assembly and scheduler
dumps don't change, so this is supposed to be a purely compile-time
improvement
Bootstrapped and regtested on aarch64-none-linux-gnu and x86_64-linux.
gcc/ChangeLog:
* sched-int.h (struct deps_desc): Add pending_barriers. Update the
reg_last_dirty description.
(deps_reg_last): Declare.
* sched-deps.cc: Include selftest-rtl.h.
(deps_reg_last): New.
(sched_analyze_insn): Materialize pending barriers when required.
Use the lazy barrier form before reload outside selective scheduling.
Reconcile reg_last_dirty entries at barriers.
(init_deps): Initialize pending_barriers.
(free_deps): Release pending_barriers.
(selftest::observed_barrier_deps): New.
(selftest::observe_barrier_dependence): New.
(selftest::assert_insn_list): New.
(selftest::test_full_lazy_barrier): New.
(selftest::test_sparse_lazy_barrier): New.
(selftest::test_lazy_barrier_join): New.
(selftest::test_lazy_barriers): New.
(selftest::sched_deps_cc_tests): Run the lazy-barrier tests.
* sched-rgn.cc (deps_join): Combine pending and materialized barrier
state.
* sel-sched-ir.cc (has_dependence_p): Assert that selective
scheduling has no pending barriers.
The region scheduler initializes one deps_desc for each basic block in a
region. Each initialization allocates and zeroes max_reg deps_reg entries.
The total allocation and zeroing work is
O (max_reg * sum (RGN_NR_BLOCKS (region))).
Before reload, max_reg is max_reg_num (). This work can therefore grow
quadratically with function size.
free_deps now empties each entry that was written. Keep these all-zero
arrays in a pool keyed by max_reg and reuse them in later regions. Reset
the list length fields before returning an array. Under -fchecking=2,
verify that every field is zero. Drain the pool in sched_deps_finish.
Selective scheduling does not return arrays to the pool because
remove_from_deps can leave an untracked control-use list.
Add a selftest that fills every list field and both length fields. It
verifies that free_deps returns the same array through the pool with all
fields cleared. Also add a compile test that drives a debug-only use
through pool release and reuse under -fchecking=2. Disabling the pool makes
the selftest fail. Dropping the reg_last_dirty recording from patch 2 makes
the compile test ICE.
On an aarch64 system, I saw a ~1.5% improvement in compile speed of
gimple-match-6 at -O3.
Generated assembly doesn't change.
Bootstrapped and tested on aarch64-none-linux-gnu and x86_64-linux.
gcc/ChangeLog:
* sched-deps.cc (reg_last_pool, reg_last_pool_max_reg): New.
(alloc_reg_last, release_reg_last): New.
(init_deps, init_deps_reg_last): Use alloc_reg_last.
(free_deps): Reset the list length fields and release reg_last to the
pool.
(sched_deps_finish): Release the pooled arrays.
(selftest::test_reg_last_pool): New.
(selftest::sched_deps_cc_tests): Run it.
reg_last_in_use does not record every reg_last entry that contains a list.
The debug-insn path adds uses and then clears reg_pending_uses before the
normal update of reg_last_in_use. The control-use path also adds lists
without updating reg_last_in_use. free_deps only walks reg_last_in_use, so
these INSN_LIST nodes are not returned to the recycler.
Add a teardown-only reg_last_dirty regset for these entries. Merge it into
reg_last_in_use in free_deps, then release all lists in the existing loop.
Do not use reg_last_dirty for dependence generation. Adding these entries
to reg_last_in_use during analysis would make barrier handling create new
anti-dependences for debug uses and control dependences for control uses.
Add a selftest that puts a use list and a control-use list in a dirty-only
entry. It calls free_deps and verifies that the INSN_LIST recycler returns
both nodes. Ignoring the dirty-only entry makes this selftest fail.
Bootstrapped and regtested on aarch64-none-linux-gnu and x86_64-linux.
gcc/ChangeLog:
* sched-int.h (struct deps_desc): Add reg_last_dirty.
* sched-deps.cc: Include selftest.h.
(sched_analyze_insn): Record debug-insn uses and control uses in
reg_last_dirty.
(init_deps): Initialize reg_last_dirty.
(free_deps): Merge reg_last_dirty into reg_last_in_use for teardown,
then clear it.
(selftest::test_dirty_reg_last_release): New.
(selftest::sched_deps_cc_tests): New. Provide an empty definition
when INSN_SCHEDULING is not defined.
* selftest-run-tests.cc (selftest::run_tests): Call
sched_deps_cc_tests.
* selftest.h (selftest::sched_deps_cc_tests): Declare.
sched-deps: clear dependency caches before freeing them
sched_deps_finish resets cache_size before it uses cache_size to clear the
dependency cache bitmaps. The cleanup loop therefore has zero iterations.
The cache arrays are freed, but their bitmap elements are not returned to
the bitmap obstack.
Move the reset after the cleanup loop.
Bootstrapped and tested on aarch64-none-linux-gnu and x86_64-linux.
gcc/ChangeLog:
* sched-deps.cc (sched_deps_finish): Reset cache_size after clearing
and freeing the dependency caches.
H.J. Lu [Fri, 31 Jul 2026 22:07:43 +0000 (06:07 +0800)]
x86: Check DECL_INCOMING_RTL for argument passing check
For argument declaration, its DECL_INCOMING_RTL holds an RTL for the
stack slot or register where the data was actually passed. If an
argument's DECL_INCOMING_RTL is a memory operand, it is passed on stack
by caller. Change ix86_argument_passed_on_stack_p to return true if the
argument's DECL_INCOMING_RTL is a memory operand.
gcc/
PR target/126320
PR target/126450
PR target/126529
* config/i386/i386.cc (ix86_spill_register_argument_p): Removed.
(ix86_argument_passed_on_stack_p): Remove the second argument.
Return true if the argument's DECL_INCOMING_RTL is a memory
operand.
(ix86_update_stack_alignment): Updated.
Jin Ma [Wed, 15 Jul 2026 14:26:18 +0000 (22:26 +0800)]
RISC-V: Avoid unused frame-pointer references in stack ties
Epilogue stack ties referenced s0 without a frame pointer, making the
unsaved register ever live. Regrename could then select it and
corrupt callee-saved state during exception unwinding.
The simpler fix of allowing equal operands in the existing pattern is
unsafe: copy propagation can fold stack_tie (sp, t3) used by stack
probing into stack_tie (sp, sp). This removes t3 = sp while CFI
still names t3 as the CFA.
Keep the two-register pattern distinct and add an SP-only form for
epilogue barriers.
gcc/ChangeLog:
* config/riscv/riscv-sr.cc (riscv_sr_match_epilogue): Accept
SP-only stack ties.
* config/riscv/riscv.cc (riscv_emit_stack_tie): Use parameterized
generators and emit SP-only ties.
(riscv_expand_epilogue): Use SP ties without a frame pointer.
* config/riscv/riscv.md (@stack_tie<mode>): Use a parameterized name.
(@stack_tie_sp<mode>): New pattern.
gcc/testsuite/ChangeLog:
* g++.target/riscv/stack-tie-unwind.C: New test.
* gcc.target/riscv/stack-tie-no-fp.c: New test.
Avinal Kumar [Tue, 4 Aug 2026 03:48:01 +0000 (21:48 -0600)]
[PATCH] match: Simplify `(A | C) == A` to `(A & C) != 0` when C is power of 2 [PR101650]
The expression (A | C) == A tests if all the bits in C are already set
in A. When C is a power of 2, this is equivalent to (A & C) != 0 which
avoids OR and compares against 0 instead of original value thus
optimizing the comparison.
Similarly (A | C) != A can be optimized to (A & C) == 0.
---
Bootstrapped and ran full test suite on x86_64 Fedora Linux.
EienMiku [Sat, 1 Aug 2026 06:37:47 +0000 (14:37 +0800)]
c++: Add missing "to" in reflection diagnostic
The diagnostic for applying ^^ to a local entity with an intervening
lambda expression reads "cannot be applied a local entity"; add the
missing "to", matching the phrasing of the other diagnostics in
get_reflection.
gcc/cp/ChangeLog:
* reflect.cc (get_reflection): Add missing "to" in diagnostic.
Marek Polacek [Fri, 31 Jul 2026 15:57:14 +0000 (11:57 -0400)]
c++/reflection: ICE with &template [:members_of():] [PR124794]
Given
struct C { template <class T> void f(T); };
we handle "&template [:^^C::f:]" correctly because the spliced
expression is
BASELINK<OVERLOAD<TEMPLATE_DECL f>>, binfo C>
which is fine: we have an OVERLOAD around the TEMPLATE_DECL and
lookup_member wrapped the whole thing in a BASELINK. But when
we're splicing members_of(^^C, ac)[0], we ended up with
OVERLOAD<TEMPLATE_DECL f>>
and then go down the wrong path in cp_parser_splice_expression.
splice already correctly adds the missing OVERLOAD but it also
needs to (maybe) add a BASELINK.
This patch also adjusts baselink_for_fns to gain a parameter
controlling if we want to ignore currently_open_derived_class.
It matters when we're in a member function of a class derived
from C and the object argument of the -> is a different derived class,
as exercised in splice17.C: pd->[:g1:] (42); in D2::mfn. There, if
we didn't ignore currently_open_derived_class, the BASELINK would
use D2 as the access_binfo, which is wrong because it has no
derivation relationship to the object type (here D1). With this
patch access_binfo will be C, which is what members_of gave us.
PR c++/124794
gcc/cp/ChangeLog:
* cp-tree.h (baselink_for_fns): Adjust declaration.
* parser.cc (cp_parser_reflect_expression): Adjust the call to
baselink_for_fns.
* reflect.cc (splice): Call baselink_for_fns.
* semantics.cc (baselink_for_fns): Add a bool parameter. If
it's true, ignore currently_open_derived_class.
[expr.reflect] says that a reflection of a pack-index-expressions
is ill-formed. But that applies to the ^^id-expression production,
not ^^type-id, in which a pack-index-specifier (for types) can be
used. So it's wrong for get_reflection to check PACK_INDEX_P, it
should only reject PACK_INDEX_EXPR.
I don't think that currently we can get there with a PACK_INDEX_EXPR
though: for a pack-index-expression Xs...[0] cp_parser_reflection_name
will consume Xs and then immediately call get_reflection which gives
an error. But leaving the PACK_INDEX_EXPR check in doesn't seem like
a bad idea.
PR c++/126546
gcc/cp/ChangeLog:
* reflect.cc (get_reflection): Check PACK_INDEX_EXPR instead of
PACK_INDEX_P.
gcc/testsuite/ChangeLog:
* g++.dg/reflect/pack-index1.C: Accept a reflection of a
pack-index-specifier. Reject a reflection of a
pack-index-expression.
* g++.dg/reflect/pack-index2.C: New test.
James K. Lowden [Mon, 3 Aug 2026 20:48:30 +0000 (16:48 -0400)]
cobol: Ignore comments in strings.
Change the file reader to recognize string constants, and not treat
the sequence "*>" as an inline comment if it appears in a
string. Credit to George Neill for the patch.
gcc/cobol/ChangeLog:
* lexio.cc (skip_quoted_literal): New function.
(remove_inline_comment): Use new function.
These changes add expanded diagnostics to error locations not addressed
in the original patch. This is done by using a new helper function that
saves the error message information for namelist related errors in a
buffer and keeping a status bit in the st_parameter_dt structure.
PR libfortran/118793
libgfortran/ChangeLog:
* io/io.h (NML_ERR_MSG_LEN): New macro.
(st_parameter_dt): Add nml_err_pending bit.
(gfc_unit): Add nml_err_msg.
* io/list_read.c (nml_error): New function.
(eat_separator): Use new function
(convert_integer): Likewise.
(convert_unsigned): Likewise.
(parse_repeat): Likewise. Save the position where the repeat
count starts and report it.
(read_logical): Likewise.
(read_integer): Likewise.
(parse_real): Likewise.
(read_complex): Likewise.
(read_real): Likewise.
(check_type): Likewise.
(list_formatted_read_scalar): Likewise.
(read_character): Likewise. Save the initial position of the value
(nml_read_obj): Unwind to nml_err_ret on a deferred error.
(namelist_read): Store deferred errors in the unit's nml_err_msg
buffer.
gcc/testsuite/ChangeLog:
* gfortran.dg/namelist_101.f90: Fix dg-do directive typo and
check the expanded diagnostic.
* gfortran.dg/namelist_104.f90: New test.
Jeff Law [Mon, 3 Aug 2026 20:48:05 +0000 (14:48 -0600)]
[committed] Fix recent msp430-elf regressions
I didn't actually bisect this, but I strongly suspect this relates to the
recent set INSN_CODE before calling insn_cost.
An obscure corner case I didn't even know existed. Inside combine we can
create nop moves which look something like (set (pc) (pc)). That would have
triggered an early out in msp430_insn_cost. After the combine change those
insns use NOOP_MOVE_INSN_CODE via special hackery in combine rather than the -1
for an unrecognized insn.
So rather than early exit from msp430_insn_code, we try to call get_attr_length
of that noop move which of course fails and triggers all kinds of testsuite
regressions.
While I considered checking earlier in the call stack, msp430 seems to be the
only port affected, so I put it down in there. Built and regression tested
where it fixes the recent regressions and causes no new regressions. Pushing
to the trunk.
gcc/
* config/msp430/msp430.cc (msp430_insn_cost): Handle insns with
NOOP_MOVE_INSN_CODE.
James K. Lowden [Mon, 3 Aug 2026 19:24:44 +0000 (15:24 -0400)]
cobol: Remove TITLE token.
TITLE was never part of ISO COBOL and is no longer mentioned in the
IBM manual. Removed it from the token list, where it was not used, and
from the lexer, where it caused errors.
gcc/cobol/ChangeLog:
* cdf.y: Update tokens.
* parse.y: Remove TITLE token.
* scan.l: Remove scanning for TITLE.
* token_names.h: Remove TITLE from token set.
James K. Lowden [Mon, 3 Aug 2026 18:06:08 +0000 (14:06 -0400)]
cobol: Avoid internal compiler error in generated lexer.
For some inputs the lexer returned: input buffer overflow, can't
enlarge buffer because scanner uses REJECT. In fact REJECT is not
used, but the message can be engendered by variable-length patterns if
they match very long input.
Use the flex input() and unput() to read the stream in advance of
pattern-matching, and restore it before the lexer continues.
gcc/cobol/ChangeLog:
* scan.l: Remove pattern that potentially matches until EOF.
* scan_ante.h (skip_string): Recast in terms of input/unput.
(yyinput): Declare function.
(yyunput): Declare function.
(is_refmod): Recast in terms of input/unput.
Robert Dubner [Mon, 3 Aug 2026 17:26:27 +0000 (13:26 -0400)]
cobol: Repairs to structure creation. [PR119461]
This PR is over a year old. The original observation that the record
layout was done in odd ways has been addressed in the intervening
months; these changes finalize those repairs. Some recursive references
(where a structure contains a pointer to structures like itself) have
been repaired (instead of using a placeholding "char *").
The use of ULONGLONG (a synonym for long_long_unsigned_type_node)
has been replaced with UINT64 (for uint64_type_node) in order to reduce
possible ambiguity.
PR cobol/119461
gcc/cobol/ChangeLog:
* genapi.cc (array_of_long_long): Renamed array_of_uint64().
(array_of_uint64): Likewise.
(parser_compile_ecs): Use array_of_uint64().
(parser_compile_dcls): Likewise.
(parser_file_add): Likewise.
(gg_array_of_file_pointers): Use new cblc_file_pp_type_node;
* gengen.cc (gg_get_structure_type_decl): Moved to structs.cc and
renamed.
* gengen.h (ULONGLONG): #define removed and replaced with UINT64.
(UINT64): Likewise.
(gg_get_structure_type_decl): Declaration removed.
* structs.cc (create_structure_type): New function.
(get_structure_type_decl): Renamed version of
gg_get_structure_type_decl().
(create_cblc_field_t): Cleaned up structure creation.
(create_referlet_t): Likewise.
(create_refer_t): Likewise.
(create_our_type_nodes): Likewise.
* structs.h (GTY): New declaration for cblc_file_pp_type_node;
* symbols.h (enum cbl_ctype_t): Removed.
Excluding an interval is now expressible, and excluding zero is just
the [-0.0, +0.0] case of it, so say so.
For some stupid historical reason which I can't remember, the irange
and prange nonzero_p() predicates returns true only for ~[0,0], so
even [5,5] returns false. When we want to test whether a range
contains a zero, we usually use the contains_p() idiom. I think this
is idotic, but perhaps there is a reason for it.
I've implemented the frange version the same way, with the wrinkle
that the constructor for ~[-0.0, +0.0] includes the possibility of
+-NAN, which means that nonzero_p() must ignore the NAN bits,
otherwise anything but a strict ~[-0.0, +0.0] +-NAN would return
false. For example, this:
x = frange(0.0, VR_ANTI_RANGE);
x.clear_nan();
x.nonzero_p(); <-- would return false
Tested on ppc64le Linux: regstrap and LAPACK. Surprisingly there are
no changes to generated output in my Fortran files, presumably because
intersect/union are enough to fold inequalities away, and also because
there are no callers to nonzero_p() for frange. Every nonzero_p()
call is guarded by prange or irange checks, but it's nice to
implement these since they are pure virtuals from the base vrange
class.
gcc/ChangeLog:
* value-range.cc (frange::set_nonzero): Implement.
(frange::nonzero_p): Implement.
(range_tests_excluding): Test set_nonzero and nonzero_p.
Reshma Roy [Thu, 30 Jul 2026 06:49:08 +0000 (12:19 +0530)]
match: Fix incorrect identification of POPCOUNT pattern [PR126466]
This fixes r17-489-g8ca1e887847e2f, which added a third 32-bit
Hacker's Delight popcount matcher. Its predicate checked
compare_tree_int (@5, 0x0F0F0F0F) twice and never validated the
final outer AND constant (@7), so any mask was accepted once the
earlier constants matched.
Require compare_tree_int (@7, 0x0000003F) so only the intended
popcount idiom is folded to IFN_POPCOUNT.
gcc/ChangeLog:
PR tree-optimization/126466
* match.pd: Fix incorrect POPCOUNT identification in the third
32-bit Hacker's Delight matcher.
Jakub Jelinek [Mon, 3 Aug 2026 09:26:11 +0000 (11:26 +0200)]
mips: Fix up creation of MD builtins with 0 arguments [PR126484]
For MIPS_SI_FTYPE_VOID and MIPS_USI_FTYPE_VOID which are meant
for functions which return (SImode) int or unsigned int and have
(void) arguments the MIPS backend creates those using
case MIPS_SI_FTYPE_VOID: types[(int) type] = build_function_type_list (intSI_type_node, void_type_node, NULL_TREE); break;
case MIPS_USI_FTYPE_VOID: types[(int) type] = build_function_type_list (unsigned_intSI_type_node, void_type_node, NULL_TREE); break;
That is wrong, because functions which don't take any arguments
(i.e. (void) or C23/C++ ()) should be using void_list_node as
TYPE_ARG_TYPES, not a TREE_LIST with void_type_node TREE_VALUE
and TREE_CHAIN being that void_list_node. Although void_list_node
also has TREE_VALUE of void_type_node, various places in the C++
FE as well as in the middle-end rely on void_list_node to be unique,
compare it using pointer comparison.
The following testcase strangely happens to compile fine when compiled
in C, but fails in C++ (which reports wrong number of arguments due
to this bug).
The following simple patch just arranges those 0 argument functions
to have the MIPS_*_FTYPE_VOID enumerators be named as before, but
in the build_function_type_list call omit that ", void_type_node" part,
so it creates correct 0 arguments FUNCTION_TYPE.
2026-08-03 Jakub Jelinek <jakub@redhat.com>
PR target/126484
* config/mips/mips-ftypes.def (MIPS_SI_FTYPE_VOID,
MIPS_USI_FTYPE_VOID): Use DEF_MIPS_FTYPE with 0 as
first argument rather than 1 and leave out ", VOID" from
second argument.
* config/mips/mips.cc (MIPS_FTYPE_NAME0): Define.
(MIPS_FTYPE_ATYPES0): Define.
testsuite/g++: force the serial PSTL backend in xtreme-header-8.C
xtreme-header-8.C is the only xtreme-header test that builds a named
module, so [basic.link]/17 applies to it and exposing a TU-local entity
is ill-formed. libstdc++ selects the PSTL backend from
__has_include(<tbb/tbb.h>), so on a machine with oneTBB installed
<execution> pulls third-party headers into the module purview. oneTBB
names namespace-scope statics and constants from inline member functions
of externally linked classes, which GCC correctly rejects, and the test
fails for reasons that have nothing to do with libstdc++ or the modules
implementation.
The failure dates back to r15-6379-g0c2ae3843261 ("c++/modules: Ignore
TU-local entities where necessary"), which added the test. The exposure
diagnostic already existed then, so the test has failed on a host with
oneTBB installed since the day it landed. That commit message does note
the hazard, "unfortunately the system headers on some
targets declare TU-local entities", but the third-party headers reached
through <execution> were not considered.
_GLIBCXX_USE_TBB_PAR_BACKEND is a documented user-overridable knob, and
libstdc++ already suppresses the TBB backend the same way for module std
(r15-5366-g7db55c0ba1ba). Define it to 0 so the test exercises what it
is meant to exercise regardless of what happens to be installed on the
test machine.
Tested on aarch64-none-linux-gnu.
gcc/testsuite/ChangeLog:
* g++.dg/modules/xtreme-header-8.C: Select the serial PSTL
backend.
[frange] Represent the inverse of a constant range
We've been throwing away the VR_ANTI_RANGE flag when setting a range,
and quietly turning it into VARYING. This patch allows setting the
inverse of a range:
frange::set (TYPE, MIN, MAX, VR_ANTI_RANGE)
This allows us to represent x != C, which is very useful for
representing non-zero.
Excluding a point is two sub-ranges:
[-INF, prev (C)] U [next (C), +INF]
range-op-float has in fact been asking for this all along.
operator_not_equal::op1_range hands us r.set (type, tmp, tmp,
VR_ANTI_RANGE) on the true edge, and operator_equal::op1_range does
the same on the false edge. They needed no changes; frange simply had
nowhere to put the answer.
Nothing here is special-cased. C == 0.0 excludes both zeros for free,
because prev (0.0) is the largest negative denormal and next (0.0) the
smallest positive one.
With this patch we finally come to parity with DOM floating point
threading, at least when it comes to the LAPACK package, which I've
taken as representative of floating point intensive code.
Tested on ppc64le Linux: regstrap, LAPACK, GSL, etc. I also
benchmarked threading counts and VRP folds, as per the last commit in
this series.
gcc/ChangeLog:
* value-range.h (class frange): Declare set_excluding.
* value-range.cc (frange::set_excluding): New.
(frange::set): Assert KIND is VR_RANGE or VR_ANTI_RANGE and that the
endpoints are not NAN. Turn a VR_ANTI_RANGE into the two sub-ranges
that exclude the point.
(frange_float_excluding, range_tests_excluding): New.
(range_tests_floats): Call range_tests_excluding.
* value-range-storage.cc (frange_storage::get_frange): Return early
for VR_VARYING, like irange_storage::get_irange.
Raise MAX_PAIRS from 1 to 2, enabling sub-ranges. This will allow us
to represent non-zero and other inequalities in a follow-up patch.
I tested how many sub-ranges would give us the most bang for the buck,
by allowing 10 sub-ranges, and seeing how many we created and used.
Even though 1 sub-range caught 91.29% of what we encountered in real
life (well, in a corpus of Fortran files from the LAPACK package), we
couldn't represent non-zero, which caused DOM to get a bunch of cases
we missed. With 2 subranges, we caught 99.63% of ranges generated,
and anything past this was useless, cause we either didn't generate
them in real life, or there was no change in generated code by having
more sub-ranges. For instance, from 3631 files, going from 2 to 3
sub-ranges caused code generation changes in 4 files (all rotmg*).
Going past 3, produced zero effect.
I also benchmarked LAPACK and the GSL package for jump threading
changes as well as VRP constant propagation. For LAPACK, we got 0.31%
more jump threading opportunities, and for GSL 1.10%. For VRP it was
the opposite, LAPACK got 0.48% more constants propagated, whereas GSL
got a mere 0.26% boost.
This may not seem like much, but just being able to represent the
inverse of a constant (e.g. nonzero) closes the gap with the DOM
internal tables. With this work, we get 100% of what DOM threading
was getting with its internal tables for the LAPACK corpus. We nuked
58 of the regressions, and I believe this will fix a few PRs we had
open for nonzero folding, as well as some signed zero missed
optimizations.
Oh, and with this patch we cause code generation differences in 2.2%
of LAPACK, and 5.48% of GSL files. I didn't dig into any of these,
but it seems other passes benefit as well. Either way, we needed a
way to represent != 0.0, which seemed like a big limitation in the
initial frange implementation, and was causing me to lose sleep in my
self-imposed break from hacking.
Tested on ppc64le: regstrap, LAPACK, GSL.
gcc/ChangeLog:
* value-range.h (class frange): Raise MAX_PAIRS to 2.
* value-range.cc: Include value-range-storage.h.
(real_from_str, range_tests_sub_ranges, range_tests_sub_ranges_nan)
(range_tests_sub_ranges_zero, range_tests_sub_ranges_storage): New.
(range_tests_floats): Call them, and adjust the disjoint-union test.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/vrp-float-15.c: New test.
* gcc.dg/tree-ssa/vrp-float-16.c: New test.
* gcc.dg/tree-ssa/vrp-float-17.c: New test.
shuffle_slide_patterns did not verify that the endpoints of a combined
slideup+slidedown sequence actually correspond to OP0's and OP1's
expected positions, allowing a non-monotonic shuffle mask to be
accepted as a valid slide pattern. This produced wrong code at -O0
for masks such as { 7, 0, 7, 0 } on a 4-element vector, as reported
in PR target/126411.
This patch checks that d->perm[0] and d->perm[vlen - 1] correspond
to the expected OP0/OP1 boundary positions (vlen - slideup_cnt and
2 * vlen - 1 - slideup_cnt respectively), and rejects the pattern
otherwise. need_slideup_p is also added to the existing second-pivot
rejection check.
PR target/126411
gcc/ChangeLog:
* config/riscv/riscv-v.cc (shuffle_slide_patterns): Check that
the sequence endpoints correspond to OP0's and OP1's expected
positions and also reject a second pivot when need_slideup_p is set.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/base/bug126411.c: New test.
Suggested-by: Raphael M Zinsly <raphael.zinsly@oss.qualcomm.com> Signed-off-by: Souradipto Das <souradiptodas6@gmail.com>
Robert Dubner [Sun, 2 Aug 2026 19:28:50 +0000 (15:28 -0400)]
cobol: Make pointer to stash location file-static. [PR126391]
COBOL variable assignments can have ON SIZE ERROR clauses. When an error
occurs and there is such a clause, the original destination value is
not changed. Since the discovery of an error happens near the end, I
chose to create a data stash for the original value; when an error is
detected, the starting value is restored from the stash.
The stash area is created using malloc, but never freed. It gets
realloced as necessary when subsequently needed. (This avoids repeated
malloc/free calls during execution.)
My mistake: I created the pointer to that area as an automatic variable
on the stack, but assigned it to a static tree. The mistake manifested
here as a temporary variable with the function context as
stored-char-length, but then later showing up with a context of prog,
leading to the ICE, because automatic variables have to have the correct
function context.
The fix was to give that variable a name and give it file-static scope.
PR cobol/126391
gcc/cobol/ChangeLog:
* move.cc (move_helper): static tree stash has file-static scope.
SSE math is disabled with -mno-sse2. Since sse-init-v2df-1.c requires
SSE math, compile sse-init-v2df-1.c with -mfpmath=sse so that SSE math
is enabled with "-mno-sse2"
* gcc.target/i386/sse-init-v2df-1.c: Compile with -mfpmath=sse.
Andrea Pinski [Sat, 1 Aug 2026 23:17:25 +0000 (16:17 -0700)]
phiopt: Factor loads, reject if the pointer types are not compatiable [PR126571]
In some cases (different address space and/or function pointers) pointers are considered
non-compatible. This means creating a phi with non-compatible pointers will fail.
This takes the easy way out and rejecting this case. This could be refined to support
the only case where address spaces are different but that case will show up much less
than the address space being different so it is not worth the trouble right now.
Pushed as obvious after bootstrap/test on x86_64-linux-gnu.
PR tree-optimization/126571
gcc/ChangeLog:
* tree-ssa-phiopt.cc (factor_out_conditional_load): Reject
when the pointer types are not compatible when creating a phi.
gcc/testsuite/ChangeLog:
* gcc.dg/torture/pr126571-1.c: New test.
* gcc.target/i386/pr126571-1.c: New test.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Thomas Koenig [Sat, 1 Aug 2026 17:03:38 +0000 (19:03 +0200)]
Fix undefined variable warning in ASSOCIATE.
This patch fixes unused warnings in ASSOCIATE constructs by setting
value_used and value_set attributes based on the associate names.
This is placed after resolution of the code. To get to the association
list, an extra argument to gfc_resolve was needed.
gcc/fortran/ChangeLog:
PR fortran/126558
* gfortran.h (gfc_resolve): Add optional argument for
an association list.
* resolve.cc (mark_assoc_used): New function.
(gfc_resolve): Use it.
gcc/testsuite/ChangeLog:
PR fortran/126558
* gfortran.dg/warn_undefined_vars_10.f90: New test.
Thomas Koenig [Sat, 1 Aug 2026 08:47:27 +0000 (10:47 +0200)]
Inline MATMUL(TRANSPOSE(A),B) for rank 1 B.
This patch implements inlining MATMUL(TRANSPOSE(A),B). For ordering
of the loops, this is an unpleasant problem because of the dependence
of c(i) on the previous iteration, but gcc was able to fully unroll
the loops at least for small sizes, and the version in the patch generated
better code.
gcc/fortran/ChangeLog:
* frontend-passes.cc (enum matrix_case): Add case A2TB1.
(matmul_lhs_realloc): Add condition for reallocation and
size checks.
(inline_matmul_assign): Handle A2TB1.
Roger Sayle [Sat, 1 Aug 2026 16:51:02 +0000 (17:51 +0100)]
x86 SSE: Improved vector initialization/construction.
This patch is a reorganization of x86's vector initialization (vec_init)
functionality to generate more efficient implementations in most/many
cases. Previously, for most (128-bit and 256-bit) vectors types,
i386-expand.cc made use of "concat" recursion to divide-and-conquor;
splitting each vector into upper and lower halves, initializing them,
then concatenating the results together. Simple and orthogonal, but
alas inefficient. This idiom is unable to take advantage of SSE's
zero extension semantics, shuffle/permutation instructions, byte-level
shifts, element insertion instructions nor vector-mode logic operations.
Unfortunately the reality is that these ISAs are irregular, as are the
patterns provided by the backend expose their instructions (which are
often available in one mode but not another).
The patch below recognizes/accepts these asymmetries, and provides
"custom" vector initialization functions for most 128-bit and 256-bit
vector modes. There are too many optimization/improvements to list
them all, but some examples are given below:
v4si f1(int x, int y) { return (v4si){x,y,0,0}; }
Before with -O2:
f1_old: movd %edi, %xmm0
movd %esi, %xmm1
punpckldq %xmm1, %xmm0
movq %xmm0, %xmm0
ret
After with -O2:
f1_new: movd %edi, %xmm0
movd %esi, %xmm1
punpckldq %xmm1, %xmm0
ret
v4si f2(int x) { return (v4si){0,x,x,0}; }
Before with -O2:
f2_old: movd %edi, %xmm2
pxor %xmm0, %xmm0
movd %edi, %xmm1
punpckldq %xmm2, %xmm0
punpcklqdq %xmm1, %xmm0
ret
f2_new: movd %edi, %xmm0
shufps $65, %xmm0, %xmm0
ret
After with -O2 -mavx2:
f4_new: movzbl %dil, %eax
vmovd %eax, %xmm0
vpinsrb $9, %edi, %xmm0, %xmm0
ret
Unfortunately, despite all of the goodness there remains one testsuite
regression: avx512vl-concatv4si-1.c whose f2 function currently expects
3 instructions before the return:
which actually contains our two optimal instructions, but between
combine, simplify-rtx and sse.md's define_insn_and_splits, we fail
to notice that the remaining operations (converting V2SI to V4SI)
are a no-op. I beg the reviewers'/maintainers' indulgence to allow
this to fail for the time being, to be solved in a follow-up patch.
This current patch is large enough already, and this remaining quirk
needs to be resolved outside the RTL expansion pass, in the later
RTL optimizers (where it is currently a missed optimization).
2026-08-01 Roger Sayle <roger@nextmovesoftware.com>
Hongtao Liu <hongtao.liu@intel.com>
gcc/ChangeLog
* config/i386/i386-expand.cc (ix86_expand_vector_init_one_nonzero):
Improved implementations for V2DI, V2DF, V4SI, V4SF, V4DI and V4DF
modes. Return false for V2SI and V2SF modes if the one non-zero
element isn't the first/lowest. Improved implementations for V8HI,
V16QI, V2HI and V8QI modes.
(nonzero_int_const_count): New helper function to count the
number of non-zero integer constants in a given array.
(nonzero_float_const_count): Likewise for SFmode floats.
(nonzero_double_const_count): Likewise for DFmode doubles.
(ix86_expand_vector_init_insert): New function to initialize a
V4SI, V8HI or V16QI vector using a sequence of pinsr[bwd] insns.
(onevar_perm_p): New local helper function.
(twovar_perm_p): Likewise.
(ix86_expand_vector_init_v2di): New mode-specific function.
(ix86_expand_vector_init_v2df): Likewise.
(ix86_expand_vector_init_v4si): Likewise.
(ix86_expand_vector_init_v4sf): Likewise.
(ix86_expand_vector_init_v8hi): Likewise.
(ix86_expand_vector_init_v16qi): Likewise.
(ix86_expand_vector_init_v4di): Likewise.
(ix86_expand_vector_init_v4df): Likewise.
(ix86_expand_vector_init_v8si): Likewise.
(ix86_expand_vector_init_v8sf): Likewise.
(ix86_expand_vector_init_general): Call the above custom helper
functions for the relevant modes.
* config/i386/sse.md (*vec_interleave_lowv4si_sse): New pattern
for (V4SImode) unpcklps on TARGET_SSE but not TARGET_SSE2.
Robert Dubner [Sat, 1 Aug 2026 11:48:37 +0000 (07:48 -0400)]
cobol: Refactor the gmath.cc "int256" structure.
The int256 structure is used for doing fixed-point arithmetic. This
rewrite incorporates "int rdigits" into the structure, so that the number
of digits to the right of the decimal point is carried as part of the
structure instead of being carried by external logic.
gcc/cobol/ChangeLog:
* copybook.h (_COPYBOOK_H): #include <sys/types.h> for macOS.
* lexio.h (struct filespan_t): Mollify cppcheck with a const variable.
* parse.y: Adjust a dbgmsg() call.
* util.cc (cobol_filename): Likewise.
Jakub Jelinek [Sat, 1 Aug 2026 09:46:49 +0000 (11:46 +0200)]
Get rid of ? true : false and simplify ? false : true
Last night I've noticed in match.pd various places like
cmp == EQ_EXPR ? true : false
and
cmp == EQ_EXPR ? false : true
I don't think that is useful, neither for readers nor for code formatting.
Sure, x ? true : false is not always equivalent to just x, but if it is
passed to a bool argument or sets a bool variable or if x is actually
a comparison in C++, it is exactly the same.
I think using just cmp == EQ_EXPR and cmp != EQ_EXPR is better.
2026-08-01 Jakub Jelinek <jakub@redhat.com>
* ipa-polymorphic-call.cc (csftc_abort_walking_p): Remove useless
"? true : false".
* tree-ssa-loop-im.cc (ref_indep_loop_p): Likewise.
* match.pd (X ==/!= !X is false/true): Replace "? false : true"
with negation of the condition.
(((C << x) & D) != 0): Likewise.
(fold_sign_changed_comparison and fold_widened_comparison): Likewise.
Remove useless "? true : false".
(if the second operand is NaN, the result is constant): Replace
"? false : true" with negation of the condition.
(__builtin_ctz (x) >= C -> (x & ((1 << C) - 1)) == 0): Likewise.
Remove useless "? true : false".
(__builtin_ctz (x) == C -> (x & ((1 << (C + 1)) - 1)) == (1 << C)):
Replace "? false : true" with negation of the condition.
(__builtin_ffs (X) == 0 -> X == 0): Remove useless "? true : false".
(__builtin_ffs (X) > 6 -> X != 0 && (X & 63) == 0): Likewise.
Replace "? false : true" with negation of the condition.
* gimple-pretty-print.cc (dump_phi_nodes): Use !(flags & TDF_GIMPLE)
instead of (flags & TDF_GIMPLE) ? false : true.
gcc/fortran/
* expr.cc (gfc_check_init_expr): Remove useless "? true : false".
(gfc_expr_check_typed): Replace "? false : true" with negation of the
condition.
* parse.cc (gfc_find_state): Likewise.
* resolve.cc (impure_stmt_fcn): Likewise.
* arith.cc (gfc_check_character_range): Remove useless
"? true : false".
* array.cc (is_constant_element): Likewise.
* decl.cc (gfc_verify_c_interop): Likewise.
* interface.cc (gfc_check_dummy_characteristics): Likewise.
* io.cc (check_open_constraints): Likewise.
(check_close_constraints): Likewise.
(check_io_constraints): Likewise.
gcc/jit/
* jit-recording.cc (recording::context::set_bool_option): Remove
useless "? true : false".
Reviewed-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Jakub Jelinek [Sat, 1 Aug 2026 09:44:55 +0000 (11:44 +0200)]
c++: Rename metafns_called to state_dependent
On Thu, Jul 30, 2026 at 10:29:23AM -0400, Jason Merrill wrote:
> OK, though we might rename metafns_called to something like state_dependent
> and mention EH in its comment. That can be a trunk-only followup.
Here it is.
2026-08-01 Jakub Jelinek <jakub@redhat.com>
* constexpr.cc (class constexpr_global_ctx): Rename metafns_called
to state_dependent, expand comment about constexpr EH.
(constexpr_global_ctx::constexpr_global_ctx ()): Rename
metafns_called to state_dependent.
(cxx_eval_cxa_builtin_fn): Likewise.
(cxx_eval_call_expression): Likewise.
Pan Li [Thu, 30 Jul 2026 07:36:36 +0000 (15:36 +0800)]
RISC-V: Add test cases for vwaddu.vv 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_vv-u16-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u16-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u16-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u16-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u16-mf4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u32-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u32-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u32-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u32-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u8-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u8-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u8-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u8-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u8-mf4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwaddu_vv-u8-mf8.c: New test.
Signed-off-by: Pan Li <pan2.li@intel.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Pan Li [Thu, 30 Jul 2026 07:36:21 +0000 (15:36 +0800)]
RISC-V: Add test cases for vwadd.vv 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_vv-i16-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i16-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i16-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i16-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i16-mf4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i32-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i32-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i32-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i32-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i8-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i8-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i8-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i8-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i8-mf4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwadd_vv-i8-mf8.c: New test.
Signed-off-by: Pan Li <pan2.li@intel.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Tomasz Kamiński [Sat, 1 Aug 2026 07:08:15 +0000 (09:08 +0200)]
libstdc++: Disable "-Winvalid-specialization" for g++ coroutine tests.
These test define specializations for libstdc++ std::coroutine_handle
definition, that is marked [[_Clang::__no_specializations]] since r17-2853-gb90df55625eb40.
Andrea Pinski [Fri, 24 Jul 2026 19:49:54 +0000 (12:49 -0700)]
gimple-fold: fix follow_outer_ssa_edges for undefined overflow cases [PR126313]
ifcombine uses match and match will use in some cases the global
range causing wrong code as the range of the ssa name might be based
on the outer condition.
The case in the bug report is:
```
# RANGE [irange] int [0, 255] MASK 0xff VALUE 0x0
_2 = (int) a.0_1;
if (_2 > 1)
goto <bb 4>; [59.00%]
else
goto <bb 3>; [41.00%]
<bb 3> [local count: 440234144]:
# RANGE [irange] int [0, 1] MASK 0x1 VALUE 0x0
_8 = (int) a.0_1;
if (_2 > _8)
goto <bb 4>; [50.00%]
else
goto <bb 5>; [50.00%]
```
So this was `(_2 <= 1 && _2 <= _8) ? goto 5 else; goto 4;`
This starts by combnining `_2 <= 1 && _2 <= _8` into `_2 <= min(1, _8)`.
But since _8 has a range of [0,1], match invokes the pattern that was added
in r14-868-gb06cfb62229f to giving `_2 <= (_8 & 1)` and then since _8 has a
range of [0,1], that expression simpifies into `_2 < _8` which is wrong.
as _2 is the same as _8. So we end up with not taking the condition any more.
The problem comes follow_outer_ssa_edges is used to save off the global range
but we return early if the variable had a type where overflow is undefined as we
can't temporary rewrite it. So the fix is to swap around the saving the off
the global range before returning early.
Bootstrapped and tested on x86_64-linux-gnu with no regressions.
PR tree-optimization/126313
gcc/ChangeLog:
* gimple-fold.cc (follow_outer_ssa_edges): Swap around returning
for undefined overflow and saving off the global range.
gcc/testsuite/ChangeLog:
* gcc.dg/torture/pr126313.c: New test.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Jason Merrill [Fri, 31 Jul 2026 17:45:48 +0000 (13:45 -0400)]
c++: early DMI parsing and {} [PR126481]
Here I thought that only name lookup and use of 'this' could change in a
complete class context, but this testcase demonstrates that an init-list
also needs deferred parsing.
PR c++/126481
gcc/cp/ChangeLog:
* parser.cc (cp_parser_early_parsing_nsdmi): Also defer {}.