Peter Damianov [Sun, 24 May 2026 18:59:46 +0000 (14:59 -0400)]
algol68: Open source files in binary mode
When building a source file with CRLF newlines on Windows, the CRLFs were
getting converted to LFs, so a86_file_read was returning "short" byte counts
and tripping an assert. Make sure files get opened in binary mode to avoid this.
gcc/algol68/ChangeLog:
* a68-lang.cc (a68_handle_option): Open file in binary mode.
* a68-parser-scanner.cc (read_source_file): Open file in binary mode.
(include_files): Likewise.
Despite a similar rule existing earlier in match.pd, this simplify
rule is needed because the front-end (before pass 006.original)
performs trivial constant optimizations, such as ~1 -> -2 on
integers (at least those defined as `int`).
Andrew Pinski [Tue, 19 May 2026 01:20:14 +0000 (18:20 -0700)]
stack_usage: Print out the user visibility name too
Since the output here should be usable via humans, we
should print out the user realable name and not just the
mangled name. For C, that means we print out the same name
twice which is fine. The mangled name is useful to correspond
the assembly with the stack usage too.
For C++ it will something like:
t.c:2:5:_Z5unopti `int unopt(int)` 16 static
Bootstrapped and tested on x86_64-linux-gnu.
gcc/ChangeLog:
* toplev.cc (output_stack_usage_1): Print out the human readable
name in quotes.
gcc/testsuite/ChangeLog:
* gcc.dg/stack-usage-1.c: Update testcase.
Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
Andrew Pinski [Fri, 22 May 2026 19:07:28 +0000 (12:07 -0700)]
ifcvt: factor: turn asserts about abnormals to conditional [PR125419]
I missed that factor_out_operators might look further up when it is doing its
factoring so we end up with a statement that ssa names that are used in abnormal
edges.
This changes the asserts to just reject the factoring instead.
Bootstrapped and tested on x86_64-linx-gnu.
PR tree-optimization/125419
gcc/ChangeLog:
* tree-if-conv.cc (factor_out_operators): Change
asserts about abnormals into a conditional to reject
it.
gcc/testsuite/ChangeLog:
* gcc.dg/torture/pr125419-1.c: New test.
Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
Jerry DeLisle [Mon, 11 May 2026 01:13:48 +0000 (18:13 -0700)]
Fortran: [PR93727] Implement EX format specifier for WRITE
These changes implement a portion of the Fortran 2018
EX format specifier for WRITE output. Hexadecimal
floating point formats for KIND=4,8,10, and 16 real
numbers if supported by the configured machine.
Format tokens are added as place holders for future leading
zero specifiers.
Remaining to be completed is proper rounding of truncated
hex float strings and implementing the READ functions. These
will be a followup patches.
PR fortran/93727
gcc/fortran/ChangeLog:
* io.cc (enum format_token): Add FMT_EX, FMT_LPS, FMT_LPZ, FMT_LZ
enums to identify specific tokens.
(format_lex): Add parsing and checking of the EXw.d and EXw.dEe edit
specifiers.
libgfortran/ChangeLog:
* io/format.c (format_lex): Add new FMT_EX token handing.
(parse_format_list): Likewise.
(next_format): Likewise
* io/io.h (write_ex): Add prototype for new function.
(internal_proto): Likewise.
* io/transfer.c (formatted_transfer_scalar_write): Use FMT_EX token.
* io/write.c (write_default_char4): White space fix.
(write_a): White space fix.
(write_boz): White space fix.
(write_decimal): White space fix.
(otoa_big): White space fix.
(write_character): White space fix.
(write_float_0): White space fix.
(write_ex): New function which uses the new helper function
get_float_hex_string() to build the hexadecimal float format for
output.
(write_real): White space fix.
(write_complex): White space fix.
(nml_write_obj): White space fix.
(namelist_write): White space fix.
* io/write_float.def: Add defines to handle the various forms of
KIND=16 floats. These handle the selection of the appropriate versions
of the frexp, fabs, and scalbn used to extract the components of the
floating point values.
(GFC_REAL_16_FREXP): New define.
(GFC_REAL_16_FABS): New define.
(GFC_REAL_16_SCALBN): New define.
(get_float_hex_string): New function which exatracts the bits and builds
the basic hexadecimal format strings into a buffer. The buffer is provided
by the caller write_ex.
(build_float_string): White space fix.
(quadmath_snprintf): White space fix.
(determine_en_precision): White space fix.
gcc/testsuite/ChangeLog:
* gfortran.dg/EXformat_1.F90: New test.
* gfortran.dg/EXformat_2.f90: New test.
Co-Authored-By: Harald Anlauf <anlauf@gcc.gnu.org>
Daniel Barboza [Sat, 17 Jan 2026 19:01:54 +0000 (16:01 -0300)]
fold-const.cc: remove fold_overflow_warning()
Remove all remaining callers of fold_overflow_warning() in
fold-const.cc, along with all associated logic.
pointer_may_wrap_p is also removed - it was being called twice, both
times to determine whether to call fold_overflow_warning() or not, and
had no other uses after fold_overflow_warning() was removed.
* gcc.dg/Wstrict-overflow-22.c: Removed, given that we do not
generated a warning for the pattern being tested.
* gcc.dg/Wstrict-overflow-5.c: Likewise.
We want to eliminate another source of Wstrict-overflow warnings from
tree_expr_nonnegative_warnv_p, via fold_overflow_warn(). At this point
strict_overflow_p is marked as ATTRIBUTE_UNUSED and we can remove it.
By removing it, the function would lost the "warnv" and be renamed to
tree_expr_nonnegative_p. This matches an existing function, that has a
different API. In a closer inspection we verify that
tree_expr_nonnegative_p is a wrapper for tree_expr_nonnegative_warn_p,
that throws a warning and leaves depth = 0 by default. This same
behavior can be achieved by removing strict_overflow_p from
tree_expr_nonnegative_warnv_p, so we'll go ahead with its rename and the
removal of the pre-existing tree_expr_nonnegative_p.
The additional strict_overflow_p local variables we've been adding to
satisfy the RECURSE() macro are all eliminated.
gcc/c-family/ChangeLog:
* c-warn.cc (warn_for_sign_compare): Remove strict_overflow_p
argument from tree_expr_nonnegative_p call.
gcc/c/ChangeLog:
* c-typeck.cc (build_conditional_expr): Likewise.
gcc/ChangeLog:
* fold-const.cc (fold_binary_loc): Likewise.
(tree_expr_nonnegative_warnv_p): Renamed to
tree_expr_nonnegative_p. Argument strict_overflow_p removed.
(tree_expr_nonnegative_p): Removed.
(RECURSE): Removed strict_overflow_p argument.
(tree_unary_nonnegative_p): Local strict_overflow_p variable
added to support the RECURSE() macro was removed.
(tree_binary_nonnegative_p): Likewise.
(tree_single_nonnegative_p): Likewise.
(tree_call_nonnegative_p): Likewise.
(tree_invalid_nonnegative_p): Likewise.
(tree_binary_nonzero_p): Removed sub_strict_overflow_p variable
from tree_expr_nonnegative_p call.
* fold-const.h (tree_expr_nonnegative_p): Removed.
(tree_expr_nonnegative_warnv_p): Renamed to
tree_expr_nonnegative_p, removed strict_overflow_p argument.
* tree-ssa-loop-manip.cc (create_iv): Removed ovf variable from
tree_expr_nonnegative_p call.
Daniel Barboza [Sat, 17 Jan 2026 19:01:52 +0000 (16:01 -0300)]
fold-const.cc: remove strict_overflow_p from tree_expr_nonnegative helpers
Before handling the fold_overflow_warn() call from
tree_expr_nonnegative_warnv_p we'll remove all remaining
strict_overflow_p flags from the helpers that are still using it.
An ATTRIBUTE_UNUSED tag was added in the strict_overflow_p argument in
tree_expr_nonnegative_warnv_p because the variable is now unused, but
removing it right now will incur a lot of non-trivial changes that would
be too much for this patch. This tag, and all the extra lines we're
adding to make RECURSE() happy, will be dealt with in the next patch.
gimple-fold.cc functions got impacted by the changes and were changed
accordingly.
gcc/ChangeLog:
* fold-const.cc (tree_call_nonnegative_warnv_p): Renamed to
tree_call_nonnegative_warnv_p.
(tree_call_nonnegative_p): Removed strict_overflow_p flag.
(tree_invalid_nonnegative_warnv_p): Renamed to
tree_invalid_nonnegative_p.
(tree_invalid_nonnegative_p): Removed strict_overflow_p flag.
(tree_expr_nonnegative_warnv_p): Added ATTRIBUTE_UNUSED tag in
the now unused strict_overflow_p argument. Removed
strict_overflow_p call from tree_invalid_nonnegative_p.
* fold-const.h (tree_call_nonnegative_warnv_p): Renamed to
tree_call_nonnegative_p.
(tree_call_nonnegative_p): Removed strict_overflow_p flag.
* gimple-fold.cc (gimple_call_nonnegative_warnv_p): Renamed to
gimple_call_nonnegative_p.
(gimple_call_nonnegative_p): Removed strict_overflow_p flag.
(gimple_stmt_nonnegative_warnv_p): Renamed to
gimple_stmt_nonnegative_p.
(gimple_stmt_nonnegative_p): Removed strict_overflow_p flag.
* gimple-fold.h (gimple_stmt_nonnegative_warnv_p): Renamed to
gimple_stmt_nonnegative_p.
(gimple_stmt_nonnegative_p): Removed strict_overflow_p flag.
* gimple-range-fold.cc (fold_using_range::fold_stmt): Removed
strict_overflow_p flag from gimple_stmt_nonnegative_p.
(fold_using_range::range_of_call): Likewise.
Daniel Barboza [Sat, 17 Jan 2026 19:01:51 +0000 (16:01 -0300)]
fold-const.cc: remove strict_overflow_p flag from tree_single_nonnegative_p
Similar to the previous patches: remove the strict_overflow_p flag to
allow us to remove the fold_overflow_warn() from the parent function
tree_single_nonnegative_warnv_p.
The changes done in fold-const.cc caused a ripple effect on
gimple-fold.cc, where we ended up doing similar changes to
gimple_assign_nonnegative_warnv_p and gimple_phi_nonnegative_warnv_p.
gcc/ChangeLog:
* fold-const.cc (tree_single_nonnegative_warnv_p): Renamed to
tree_single_nonnegative_p.
(tree_single_nonnegative_p): Removed strict_overflow_p flag.
(tree_expr_nonnegative_warnv_p): Removed strict_overflow_p flag
from tree_single_nonnegative_p call.
* fold-const.h (tree_single_nonnegative_warnv_p): Renamed to
tree_single_nonnegative_p.
(tree_single_nonnegative_p): Removed strict_overflow_p flag.
* gimple-fold.cc (gimple_assign_nonnegative_warnv_p): Renamed to
gimple_assign_nonnegative_p.
(gimple_assign_nonnegative_p): Removed strict_overflow_p flag.
(gimple_phi_nonnegative_warnv_p): Renamed to
gimple_phi_nonnegative_p.
(gimple_phi_nonnegative_p): Removed strict_overflow_p flag.
(gimple_stmt_nonnegative_warnv_p): Removed strict_overflow_p
flag from gimple_phi_nonnegative_p and gimple_assign_nonnegative_p
calls.
Daniel Barboza [Sat, 17 Jan 2026 19:01:50 +0000 (16:01 -0300)]
fold-const.cc: remove strict_overflow_p from tree_unary_nonnegative
Similar to what was done with tree_binary_nonnegative_p in the previous
patch, we want to remove overflow flags from all
tree_unary_nonnegative_warnv_p helpers, and then remove all overflow
flags from the parent helper itself.
gcc/ChangeLog:
* fold-const.cc (tree_unary_nonnegative_warnv_p): Renamed to
tree_unary_nonnegative_p.
(tree_unary_nonnegative_p): Removed strict_overflow_p flag.
(tree_expr_nonnegative_warnv_p): Removed strict_overflow_flag
from tree_unary_nonnegative_p calls.
* fold-const.h (tree_unary_nonnegative_warnv_p): Renamed to
tree_unary_nonnegative_p.
(tree_unary_nonnegative_p): Removed strict_overflow_p flag.
* gimple-fold.cc (gimple_assign_nonnegative_warnv_p): Removed
strict_overflow_flag from tree_unary_nonnegative_p calls.
gcc/testsuite/ChangeLog:
* gcc.dg/Wstrict-overflow-24.c: Removed since the pattern
doesn't throw warnings anymore.
* gcc.dg/Wstrict-overflow-9.c: Likewise.
Daniel Barboza [Sat, 17 Jan 2026 19:01:49 +0000 (16:01 -0300)]
fold-const.cc: remove strict_overflow_p from tree_binary_nonnegative
We want to remove a fold_overflow_warn() nested inside
tree_exp_nonnegative_warnv_p. This function uses a lot of helpers, and
some of them do recursive calls for the helper itself.
Let's deal with strict_overflow_p flags for each helper first, starting
with tree_binary_nonnegative_warnv_p, that is now renamed to
tree_binary_nonnegative_p since it doesn't handle warnings anymore.
The RECURSE() macro expects a strict_overflow_p variable to be valid in
its scope, so we can't just remove the flag from the function
parameters. We're adding a temporary block that declares a local
strict_overflow_p variable to make RECURSE() happy. These declarations
will all be removed when we deal with tree_expr_nonnegative_warnv_p.
gcc/ChangeLog:
* fold-const.cc (tree_binary_nonnegative_warnv_p): Renamed to
tree_binary_nonnegative_p.
(tree_binary_nonnegative_p): Removed strict_overflow_p flag. Add
a local variable with the same name for RECURSE() that we'll
remove later.
(tree_expr_nonnegative_warnv_p): Removed strict_overflow_p flag
from tree_binary_nonnegative_p call.
* fold-const.h (tree_binary_nonnegative_warnv_p): Renamed to
tree_binary_nonnegative_p.
(tree_binary_nonnegative_p): Removed strict_overflow_p flag.
* gimple-fold.cc (gimple_assign_nonnegative_warnv_p): Likewise.
gcc/testsuite/ChangeLog:
* gcc.dg/pr56355-1.c: Removed since it's a warning check test
and we do not emit warnings for the code being tested.
Daniel Barboza [Sat, 17 Jan 2026 19:01:48 +0000 (16:01 -0300)]
fold-const.cc: remove strict_overflow_p from maybe_canonicalize_comparison
Remove the strict overflow flag from maybe_canonicalize_comparison
functions. All related fold_overflow_warning calls are also removed.
gcc/ChangeLog:
* fold-const.cc (maybe_canonicalize_comparison_1): Removed
strict_overflow_p flag.
(maybe_canonicalize_comparison): Removed strict_overflow_p
flag and all fold_overflow_warning calls.
Daniel Barboza [Sat, 17 Jan 2026 19:01:47 +0000 (16:01 -0300)]
fold-const.cc: remove strict_overflow_p from tree_expr_nonzero_warnv_p
After changing all its internal helpers we're ready to change
tree_expr_nonzero_warnv_p. By removing the strict_overflow_p flag from
it we'll make the existing tree_expr_nonzero_p unneeded. We'll delete it
and rename tree_expr_nonzero_warnv_p to tree_expr_nonzero_p without
changing the API and the behavior for existing callers.
And we'll end up removing a fold_overflow_warn() call, which was our
whole idea in the end.
gcc/ChangeLog:
* fold-const.cc (tree_expr_nonzero_warnv_p): Renamed to
tree_expr_nonzero_p and removed the strict_overflow_p flag.
(tree_expr_nonzero_p): Removed it since it's now redundant with
tree_expr_nonzero_warnv_p.
(tree_unary_nonzero_p): Removed the local sub_strict_overflow_p
flag from the tree_expr_nonzero_p call.
(tree_binary_nonzero_p): Likewise.
(tree_single_nonzero_p): Likewise.
Daniel Barboza [Sat, 17 Jan 2026 19:01:44 +0000 (16:01 -0300)]
fold-const.cc: remove strict_overflow_p from tree_unary_nonzero_warnv_p
This helper is called by tree_expr_nonzero_warnv_p(), a helper that is
gating a call to fold_overflow_warning() that we want to eliminate.
For now let's change the comment from tree_expr_nonzero_warnv_p() to
mention that we're throwing overflow warnings just for certain cases,
not all. We'll change that comment again when we get to work on
tree_expr_nonzero_warnv_p().
The helper is renamed to remove the "warn" from its name since it
doesn't throw or set any overflow warnings anymore.
gcc/ChangeLog:
* fold-const.cc (mask_with_tz): Changed comment that describes
tree_expr_nonzero_warnv_p warn on overflow behavior.
(tree_expr_nonzero_warnv_p): Removed strict_overflow_p flag.
(tree_unary_nonzero_warnv_p): Renamed to tree_unary_nonzero_p.
(tree_unary_nonzero_p): Removed strict_overflow_p flag.
* fold-const.h (tree_unary_nonzero_warnv_p): Renamed to
tree_unary_nonzero_p.
(tree_unary_nonzero_p): Removed strict_overflow_p flag.
Daniel Barboza [Sat, 17 Jan 2026 19:01:42 +0000 (16:01 -0300)]
fold-const.cc: remove strict_overflow flag from make_range helpers
This is a first step towards deprecating -Wstrict_overflow. The warning
is rooted in several places throughout the code, fold-const.cc functions
being one of them (via fold_overload_warn()).
These helpers are used in other files as well so the approach taken is to
gradually remove it from fold-const.cc while fixing the existing callers
along the way.
Philipp Tomsich [Sat, 23 May 2026 16:31:11 +0000 (10:31 -0600)]
[RISC-V] Improve slli+zext+andi sequence for RISC-V
So this is another patch mostly from the VRULL team. Given something like
this:
> #define T int
> typedef long unsigned int size_t;
> extern void *xcalloc (size_t, size_t) ;
> typedef struct sparseset_def
> {
> unsigned T *dense;
> unsigned T *sparse;
> unsigned T members;
> unsigned T size;
> unsigned T iter;
> unsigned char iter_inc;
> unsigned char iterating;
> unsigned T elms[2];
> } *sparseset;
> sparseset
> sparseset_alloc (unsigned T n_elms)
> {
> unsigned T n_bytes = sizeof (struct sparseset_def)
> + ((n_elms - 1) * 2 * sizeof (unsigned T));
> sparseset set = (sparseset) xcalloc (1, n_bytes);
> return set;
> }
It currently compiles into this with rv64gcb:
> addi a1,a0,4
> slli a1,a1,3
> zext.w a1,a1
> andi a1,a1,-8
> li a0,1
> tail xcalloc
But we can do better. In particular the slli+zext+andi sequence can be
improved into:
The new pattern needs to be a define_insn_and_split due to a chain of
define_insn_and_split patterns that start with mvconst_internal 🙁
To avoid regressing zba-shadd.c I had to turn an existing define_split into a
define_insn_and_split 🙁 🙁
This has been regression tested on riscv32-elf and riscv64-elf. It's been
bootstrapped and regression tested on the K1 design (where is likely triggered
a few times during bootstrap) and on the Pioneer (which doesn't have Zba, so
this pattern should never trigger). Waiting on pre-commit testing's verdict.
gcc/
* config/riscv/bitmanip.md (slli_slli_uw): New pattern.
(plus+and+ashift splitter): Turn into define_insn_and_split.
(riscv_slli_uw): Renamed from *slliuw.
gcc/testsuite
* gcc.target/riscv/and-shift-1.c: New test.
Paul Thomas [Sat, 23 May 2026 13:58:36 +0000 (14:58 +0100)]
Fortran: Fix scalar class to derived select type entities. [PR125263]
2026-05-23 Paul Thomas <pault@gcc.gnu.org>
gcc/fortran
PR fortran/125263
* trans-expr.cc (gfc_trans_assignment_1): Pass scalar class to
derived type assignment expressions to gfc_trans_scalar_assign.
gcc/testsuite/
PR fortran/125263
* gfortran.dg/pr125263.f90: New test.
Paul Thomas [Sat, 23 May 2026 13:40:19 +0000 (14:40 +0100)]
Fortran: Fix ICE in allocatable finalization expression [PR125391]
2026-05-23 Paul Thomas <pault@gcc.gnu.org>
gcc/fortran
PR fortran/125391
* trans.cc (gfc_assignment_finalizer_call): For finalization of
allocatable and pointer lhs before assignment, gfc_conv_expr
should be used with se.descriptor_only. This avoids implicit of
set_factored_descriptor_value by gfc_conv_expr_descriptor.
gcc/testsuite/
PR fortran/125391
* gfortran.dg/pr125391.f90: New test.
Dimitar Dimitrov [Wed, 25 Mar 2026 20:34:05 +0000 (22:34 +0200)]
pru: Inline muldi3 when optimizing for speed
When optimizing for speed, it is faster to inline the 32-bit
multiplication sub-operations, instead of calling a library function.
This saves instruction cycles spent for preparing a call to the multi64
library function, at the expense of duplication in text section.
The inlined muldi3 operation uses only a few temporary registers,
so there should be no negative effects due to increased register
pressure. Even more, the register pressure may even decrease with
inlining because the number of temporary registers is much lower than
the number of caller-saved registers for PRU.
gcc/ChangeLog:
* config/pru/constraints.md: Prevent allocating r27 as
SImode destination for mulsi3 pattern.
* config/pru/pru.h (enum reg_class): Expand MULDST_REGS
to allow fitting DImode.
* config/pru/pru.md (umulsidi3): New pattern.
(muldi3): Ditto.
Jason Merrill [Fri, 22 May 2026 16:57:09 +0000 (12:57 -0400)]
c++: defaulted ctor vs template ctor [PR125135]
Here we were getting into a CWG1092 cycle again through
check_non_deducible_conversions, trying to lazily declare the RE move
constructor, looking for a constructor to move A, considering the
constructor template which takes RE&, and so trying to lazily declare the RE
constructors again.
Julian Brown [Fri, 22 May 2026 21:55:50 +0000 (23:55 +0200)]
OpenMP: Enable 'declare mapper' mappers for 'target update' directives
This patch enables use of 'declare mapper' for 'target update' directives,
for C and C++ but not yet for Fortran.
There are some implementation choices here and some
"read-between-the-lines" consequences regarding this functionality,
as follows:
* It is possible to invoke a mapper which contains clauses that
don't make sense for a given 'target update' operation. E.g. if a
mapper definition specifies a "from:" mapping and the user does "target
update to(...)" which triggers that mapper, the resulting map kind
(OpenMP 5.2, "Table 5.3: Map-Type Decay of Map Type Combinations")
is "alloc" (and for the inverse case "release"). For such cases,
an '-Wopenmp' warning is issued and the map clause in question is
dropped from the mapper expansion. (Other choices might be to make
this an error, or to do the same thing but silently, or warn only
given some special option.)
gcc/c-family/ChangeLog:
* c-common.h (enum c_omp_region_type): Add C_ORT_UPDATE and
C_ORT_OMP_UPDATE codes.
* c-omp.cc (omp_basic_map_kind_name): New function.
(omp_instantiate_mapper): Add LOC parameter and 'target update'
support.
(c_omp_instantiate_mappers): Add 'target update' support.
Wang Yaduo [Fri, 22 May 2026 17:26:10 +0000 (11:26 -0600)]
[PATCH v4] RISC-V: Add per-type reduction costs to the vector cost model
Add type-specific reduction costs for integer (i8/i16/i32/i64) and
floating-point (f16/f32/f64) reductions. Ordered (fold-left) FP
reductions receive separate higher costs. Use helpers is_reduction()
and get_reduction_cost() for readability. Adjust affected tests to use
-mmax-vectorization.
Changes in v4:
- Fix failure in gcc.target/riscv/rvv/autovec/cond/pr111401.c by
adding -mmax-vectorization.
Tested locally with qemu, all affected tests pass.
gcc/
* config/riscv/riscv-protos.h (common_vector_cost): Add
reduc_i8_cost through reduc_f64_cost and
reduc_f{16,32,64}_ordered_cost.
* config/riscv/riscv.cc: Set costs in rvv_vls_vector_cost and
rvv_vla_vector_cost.
* config/riscv/riscv-vector-costs.cc (is_reduction): New helper.
(get_reduction_cost): New helper.
(costs::adjust_stmt_cost): Use them for vec_to_scalar kind.
cfgrtl: Forbid forwarder blocks from having clobbers [PR125375]
In this testcase, jump2 was presented with:
L1:
set the return register
do epilogue stuff
goto L4
L2:
do the same epilogue stuff
L3:
clobber the return register
goto L4
The question then is: is the L3 block a forwarder block? It is a
forwarder block in the sense that a jump to L3 can be replaced with a
jump to L4. But it isn't a forwarder block in the sense of a jump to L3
being equivalent to a jump to L4. In particular, a jump to L4 cannot be
merged with a jump or fallthrough to L3 unless we can prove that the
clobber is valid for both paths.
In the testcase, L3 was marked as a forwarder block and so cross-jumping
created:
L1:
set the return register
L2:
do epilogue stuff
L3:
clobber the return register
goto L4
The set of the return register was then inevitably deleted as dead.
The clobber in this case is of the return register. But the same
principle/problem would apply to any clobber. We can't introduce new
clobbers on a path without proving that the clobbered thing is dead.
This question arises due to an old quirk of active_insn_p that predates
CVS history:
Thus a clobber is "active" before RA but not after it. This means
that, according to flow_active_insn_p, a block with a clobber is not
a forwarder block before RA, but can be afterwards.
The "most optimal" solution would probably be to split the concept
of forwarder block into two, one that allows clobbers and one that
doesn't. However, that would be difficult to retrofit at this stage
and isn't likely to be suitable for backporting. This patch therefore
takes the more conservative approach of making flow_active_insn_p treat
clobbers in the same way after RA as it does before RA.
Some of this infrastructure is probably ripe for updating. For example,
flow might have required explicit uses of the return register, but DF
should cope well enough without. We should probably also check
whether the active_insn_p behaviour still makes sense.
gcc/
PR rtl-optimization/125375
* cfgrtl.cc (flow_active_insn_p): Return true for clobbers.
>>> Produces 2 regressions:
>>> |
>>> | regressions.sum:
>>> | Running gcc:gcc.target/aarch64/aarch64.exp ...
>>> | FAIL: gcc.target/aarch64/tbz_1.c check-function-bodies g1
>>> | FAIL: gcc.target/aarch64/tbz_1.c check-function-bodies g2
>> I've reproduced this locally. I haven't gotten into the debug cycle
>> yet, but wanted folks to know it's mine AFAICT to avoid duplicating
>> debugging efforts.
>
> I think the fix is just a testcase fix.
> Currently the testcase has:
> ** tbnz w[0-9]+, #?0, .L([0-9]+)
>
> But that should just can be:
> ** tbnz [wx][0-9]+, #?0, .L([0-9]+)
>
> to match both x0 and w0 there. But are valid in this case with bit 0.
> For both g1 and g2.
Yea, so I wanted to verify this was behaving per expectation. It is. We have
this in g1:
We can trivially see that the zero extension is pointless because the value is
masked with 0x1 immediately thereafter. So ext-dce replaces the zero_extend
with a subreg which then simplifies the sequence into:
Jonathan Wakely [Fri, 22 May 2026 12:25:57 +0000 (13:25 +0100)]
libstdc++: Fix some test failures due to vector using allocate_at_least
Some std::vector tests are FAILing for 32-bit targets because
std::vector now rounds up allocations to an alignment boundary,
perturbing the expected capacity of the vectors in the tests.
Tweak the tests so that they don't depend on the precise capacity, which
is unspecified anyway.
The 23_containers/vector/modifiers/insert_vs_emplace.cc test still
FAILs, that needs a different fix.
libstdc++-v3/ChangeLog:
* testsuite/23_containers/vector/modifiers/emplace/self_emplace.cc:
Ensure there is no unused capacity before inserting new element.
* testsuite/23_containers/vector/modifiers/insert/self_insert.cc:
Likewise.
Jakub Jelinek [Fri, 22 May 2026 09:19:18 +0000 (11:19 +0200)]
match.pd: Handle BUILT_IN_BITREVERSE8 like other BUILT_IN_BITREVERSE* [PR125399]
I've mistakenly omitted BUILT_IN_BITREVERSE8 in the BITREVERSE
operator list.
The following patch fixes that, plus extends the __builtin_bitreverse32
test with one further check and duplicates the test for the other
builtins, i.e. __builtin_bitreverse{8,16,64,128}.
* gcc.dg/builtin-bitreverse-4.c (foo9): New function.
* gcc.dg/builtin-bitreverse-5.c: New test.
* gcc.dg/builtin-bitreverse-6.c: New test.
* gcc.dg/builtin-bitreverse-7.c: New test.
* gcc.dg/builtin-bitreverse-8.c: New test.
The following patch attempts to implement the C++26
P3074R7 - trivial unions (was std::uninitialized<T>)
paperand proposed resolution of
CWG3189 - Implicitly deleted destructors for union-like classes
with the exception of the
#define __cpp_lib_constexpr_inplace_vector 2025XXL // also in <inplace_vector>
addition and possibly needed <inplace_vector> changes (will defer that to
Jonathan / Tomasz) and except for the changes in [class.default.ctor]/4 which
were reverted by P3726R2 later on .
There is one change which doesn't affect just C++26 but also older versions
of the standard, https://eel.is/c++draft/class.default.ctor#2.2 or its older
counterparts, e.g. C++11 had in [class.ctor]/5
"any non-variant non-static data member of const-qualified type (or array thereof)
with no brace-or-equal-initializer does not have a user-provided default
constructor"
but we've been ignoring the "non-variant" part thereof and diagnosing it
for variant members too. Note, this is related to the other unimplemented
rule I've posted a patch earlier for that was dismissed (reject
all variant members const before C++26), so some cases which we've rejected
for a wrong reason will now be accepted when they are still invalid before
C++26.
2026-05-22 Jakub Jelinek <jakub@redhat.com>
PR c++/119059
gcc/c-family/
* c-cppbuiltin.cc (c_cpp_builtins): For C++26 predefine
__cpp_trivial_union to 202502L.
gcc/cp/
* method.cc: Implement C++26 P3074R7 - trivial unions (was
std::uninitialized<T>) (except the sentence removed again in P3726R2)
and proposed resolution of CWG3189 - Implicitly deleted destructors
for union-like classes.
(walk_field_subobs): Don't do default_init_uninitialized_part checks
for variant members. Don't check subobject ctor/dtor for variant
members for ctor/inheriting ctor or when subobject doesn't have member
initializer for dtor and it is either the dtor_from_ctor case or
the current class doesn't have user provided ctors.
* class.cc (check_field_decl): Don't or in
TYPE_HAS_NONTRIVIAL_DESTRUCTOR or TYPE_HAS_DEFAULT_CONSTRUCTOR of
variant subobjects for C++26.
gcc/testsuite/
* g++.dg/DRs/dr2581-1.C: Expect warning for __cpp_trivial_union.
* g++.dg/DRs/dr2581-2.C: Expect error for __cpp_trivial_union.
* g++.dg/cpp26/feat-cxx26.C: Add __cpp_trivial_union checking.
* g++.dg/cpp26/trivial-union1.C: New test.
* g++.dg/cpp26/trivial-union2.C: New test.
* g++.dg/reflect/trivial-union1.C: New test.
* g++.dg/reflect/type_trait6.C: Adjust expected result of
one is_destructible_type and two is_nothrow_destructible_type calls.
* g++.dg/reflect/is_constructible_type1.C: Adjust expected result
of one is_constructible_type call.
* g++.dg/init/pr43719.C: Don't expect one error.
* g++.dg/init/pr25811.C: Don't expect 3 diagnostic messages,
instead expect a different one for C++98 only.
* g++.dg/other/anon-union2.C: Only expect one diagnostic for
C++23 and older.
* g++.dg/cpp0x/union1.C: Only expect 6 diagnostic messages for
C++23 and older.
* g++.dg/cpp0x/union4.C: Only expect 3 diagnostic messages for
C++23 and older.
* g++.dg/cpp0x/defaulted2.C: Only expect 2 diagnostic messages for
C++23 and older.
Kishan Parmar [Fri, 22 May 2026 06:55:25 +0000 (12:25 +0530)]
rs6000: Add MPCCORE to TARGET_NO_LWSYNC
The MPC8xx PowerQUICC family only implements full 'sync', 'lwsync'
is not yet supported. The CPU actually checks that the
should-be-zero bits of the sync instruction are zero, and faults
otherwise - same situation as for E500 cores.
Fix emitting 'lwsync' instructions by adding PROCESSOR_MPCCORE
to the TARGET_NO_LWSYNC define.
Encountered an illegal instruction crash (in libstdc++ atomics) and
verified the fix on actual MPC860 hardware.
Avinal Kumar [Thu, 21 May 2026 10:24:12 +0000 (15:54 +0530)]
match: Handle X != INT_MIN ? -X : INT_MIN [PR125050]
The pattern X != C1 ? -X : C2 currently bails out when C1 is
INT_MIN and the type doesn't wrap, because a signed negation
of INT_MIN is undefined behavior. But the whole expression is
well-defined: it is equivalent to (signed)(-(unsigned)X).
Handle the wi::only_sign_bit_p case by emitting an unsigned
negate instead of giving up, mirroring what the abs pattern
already does for the same edge case.
PR tree-optimization/125050
gcc/ChangeLog:
* match.pd: (X != C1 ? -X : C2): Handle C1 being INT_MIN
by emitting (signed)(-(unsigned)X) instead of bailing out.
gcc/testsuite/ChangeLog:
* gcc.dg/fold-condneg-2.c: Update expected optimization.
* gcc.dg/pr125050.c: New test.
* gcc.dg/tree-ssa/phi-opt-50.c: New test.
* gcc.dg/tree-ssa/phi-opt-51.c: New test.
Jonathan Wakely [Thu, 21 May 2026 22:13:53 +0000 (23:13 +0100)]
libstdc++: Combine duplicated tests for <atomic>
The types_std_c++0x.cc and types_std_c++20.cc tests are almost
identical, and the latter is redundant now that we can (and do) run all
tests for any -std option, and run with -std=gnu++20 by default.
Likewise for the _neg.cc tests.
Merge the C++20-specific parts into the c++0x tests and remove the c++20
ones.
libstdc++-v3/ChangeLog:
* testsuite/29_atomics/headers/atomic/types_std_c++0x.cc: Check
for C++20 std::memory_order enum. Use feature test macro for
char8_t.
* testsuite/29_atomics/headers/atomic/types_std_c++0x_neg.cc:
Add check for atomic_char8_t.
* testsuite/29_atomics/headers/atomic/types_std_c++20.cc:
Removed.
* testsuite/29_atomics/headers/atomic/types_std_c++20_neg.cc:
Removed.
* testsuite/29_atomics/headers/atomic/types_std_c++2a.cc:
Removed.
avoid-store-forwarding: Continue BB analysis after complex memory ops
The pass aborted analysis of the entire remaining basic block when it
encountered a complex memory operation (non-simple store/load).
Store-forwarding opportunities after the complex operation were silently
missed.
Replace the early return with a flush-and-continue: clear the pending
store candidates and keep scanning. The two other flush sites
(throwing insns, unknown-size memory) already use this pattern.
gcc/ChangeLog:
* avoid-store-forwarding.cc
(store_forwarding_analyzer::avoid_store_forwarding): Replace
return with flush-and-continue for complex memory operations.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/avoid-store-forwarding-6.c: New test.
avoid-store-forwarding: Reject bit-inserts that clobber live hard regs
The bit-insert sequences generated by store_bit_field can clobber hard
registers (such as the flags register on x86) as a side effect. If
such a register is live at the insertion point, the transformation
would corrupt it, breaking flag-dependent sequences like carry chains
(see PR119795).
Add a liveness check in process_store_forwarding: after generating the
bit-insert sequences, collect the hard registers they clobber (excluding
the intended destination) and reject the transformation if any of them
is live at the insertion point. Per-insn live-out hard-register sets
are computed once per BB by simulating it backward with
df_simulate_one_insn_backwards, and cached in store_forwarding_analyzer
so subsequent forwarding candidates in the same BB reuse the result.
The cache is populated lazily on the first candidate that produces
non-empty clobbers, so on targets where bit-inserts have no side-effect
clobbers (such as aarch64 bfi) the BB walk never runs.
gcc/ChangeLog:
* avoid-store-forwarding.cc: Include regs.h.
(record_hard_reg_clobbers): New callback.
(store_forwarding_analyzer::m_bb_live_after): New cache.
(store_forwarding_analyzer::compute_bb_live_after): New helper.
(store_forwarding_analyzer::process_store_forwarding): Add
liveness check for hard registers clobbered by bit-insert
sequences, using the cached per-BB live-out information, and
evict the load_insn entry from the cache before delete_insn
in the load-elim path.
(store_forwarding_analyzer::avoid_store_forwarding): Clear the
per-BB liveness cache on entry.
The store_exprs_del vector was introduced in the PR119795 fix as a
conservative safety measure alongside the actual bug fixes (adding
forwardings.truncate(0) on vector mismatch and true_dependence
detection). It tracks deleted store candidates and blocks forwarding
when a deleted store's range overlaps with the load.
However, this check is not needed for correctness. In the non-load-
elimination path the load is kept and reads all bytes from memory;
the bit-insert only overwrites forwarded bytes. Deleted stores remain
in the instruction stream, so their memory effects are visible to the
load. In the load-elimination path, all bytes must be covered by
forwarded stores (enforced by the bitmap check), so missing stores
cannot cause partial updates.
The vector grows monotonically through the basic block and is scanned
for each forwarding candidate, producing O(n^2) behavior for large
basic blocks.
Remove the mechanism entirely. This eliminates the O(n^2) scan and
simplifies the code.
gcc/ChangeLog:
* avoid-store-forwarding.cc
(store_forwarding_analyzer::avoid_store_forwarding): Remove
store_exprs_del vector and all associated tracking. Remove the
same_range_as_removed check from the forwarding loop. Update
block comment.
libffi/ChangeLog:
PR libffi/117635
* testsuite/lib/libffi.exp (load_gcc_lib): Load library from GCC
testsuite.
Load target-supports.exp and target-supports-dg.exp.
(libffi-init): Use libraries in GCC build tree.
Pass correct flags on darwin.
(libffi_target_compile): If '--with-build-sysroot=[...]' was
specified, use it for build-tree testing. Link with
-shared-libgcc -lstdc++ for C++ sources.
Signed-off-by: Pietro Monteiro <pietro@sociotechnical.xyz>
Marek Polacek [Tue, 19 May 2026 00:51:06 +0000 (20:51 -0400)]
c++: fix bogus error with xobj member function [PR125330]
In this test since r17-472 we issue a bogus "not declared in this scope"
error when parsing the requires because we failed to pushdecl. Xobj
parameters reuse the default argument field (in _parameter_declaration)
so we also have to check this_identifier.
PR c++/125330
gcc/cp/ChangeLog:
* parser.cc (cp_parser_parameter_declaration_list): Also
pushdecl when parameter->default_argument is this_identifier.
Jason Merrill [Tue, 19 May 2026 09:15:00 +0000 (05:15 -0400)]
c++: another constexpr empty class tweak
While talking about PR125336, I noticed that we were unnecessarily omitting
a subobject CONSTRUCTOR for non-potentially-overlapping fields of empty
class type. Let's check is_empty_field instead.
Jason Merrill [Thu, 21 May 2026 19:02:21 +0000 (15:02 -0400)]
c++: this capture in template [PR125384]
The r16-1019 change to special-case 'this' capture handling dropped the
'const' qualifier from the capture proxy, so the call to rvalue in
finish_this_expr no longer built a NOP_EXPR to express dropping that
'const'.
PR c++/125384
PR c++/113563
gcc/cp/ChangeLog:
* lambda.cc (build_capture_proxy): 'this' capture proxy is const.
Wilco Dijkstra [Mon, 9 Feb 2026 19:01:19 +0000 (19:01 +0000)]
AArch64: Add PIC/PIE support to large model [PR 123791]
Use an indirection via GOT for data accesses that might be out of range of
ADRP. Using the GOT avoids placing relro symbol references in literal pools
(PR 123791). It also allows the large model to trivially support PIC/PIE.
Constants and readonly data use ADRP since the maximum text size is 2GB in
the large model [1]. The code quality of -mcmodel=large improves dramatically
as a result: codesize of SPEC2017 reduces by 2.2%.
gcc:
PR target/123791
* config/aarch64/aarch64.cc (aarch64_cannot_force_const_mem): Remove
forcing symbol references to const mem.
(aarch64_can_use_per_function_literal_pools_p): Return false for
large model.
(aarch64_use_blocks_for_constant_p): Update comment.
(initialize_aarch64_code_model): Allow PIC/PIE.
(aarch64_classify_symbol): Use SYMBOL_SMALL_ABSOLUTE for constant
references and SYMBOL_SMALL_GOT_4G for writeable data.
Jakub Jelinek [Thu, 21 May 2026 14:26:22 +0000 (16:26 +0200)]
c++: Fix up handling of name independent decls in coroutine lowering [PR125376]
For variables which do have non-NULL DECL_NAME, register_local_var_uses
uses either that name or name_depth_idx (that itself is a bug as it
can clash with user variables named that way) for the fields. In C++26
we can have multiple _ variables in the same scope, so the following
testcase is miscompiled by using the same FIELD_DECL multiple times
(once for the first _ variable, once for the second one).
The following patch fixes it by pretending such variables don't have
a name, so it uses a serial number then instead.
2026-05-21 Jakub Jelinek <jakub@redhat.com>
PR c++/125376
* coroutines.cc (register_local_var_uses): Ignore DECL_NAME for
name independent decls.
Thomas Koenig [Thu, 21 May 2026 13:34:04 +0000 (15:34 +0200)]
Fix PR 125379, ICE with BIND(C) and PRIVATE
This fixes a recent regression introduced by my patch for PR 125902. The
problem was that, for private entities, the symbols cannot be found by
gfc_find_symbol a gsymbol's namespace. This patch uses the approach of
iterating over all the symbols to look for the right name if direct
lookup fails.
gcc/fortran/ChangeLog:
PR fortran/125379
* gfortran.h (gfc_find_symbol_by_name): Add prototype.
* resolve.cc (gfc_verify_binding_labels): Call gfc_find_symbol_by_name
if direct lookup fails.
* symbol.cc (compare_target_sym_name): New function.
(gfc_find_symbol_by_name): New function.
gcc/testsuite/ChangeLog:
PR fortran/125379
* gfortran.dg/binding_label_tests_38.f90: New test.
Xi Ruoyao [Fri, 15 May 2026 03:46:35 +0000 (11:46 +0800)]
riscv: Fix SSP assembly with xtheadmemidx [PR 125320]
The m constraint accepts memory operands suitable for memory load/store
instructions in extensions, not only the ld/sd instructions. So we
cannot always use ld/sd in the SSP instruction sequences.
Call riscv_output_move() for the correct assembly template instead.
PR target/125320
gcc/
* config/riscv/riscv.md (stack_protect_test_<mode>): Call
riscv_output_move() instead of hard coding <load>.
(stack_protect_set_<mode>): Call riscv_output_move() instead of
hard coding <load> and <store>.
Jonathan Wakely [Tue, 19 May 2026 16:44:44 +0000 (17:44 +0100)]
libstdc++: Deprecate numeric_limits::has_denorm for C++23
The paper P2614R2 was approved in Issaquah, 2023. It deprecates the
float_denorm_style enumeration type, its enumerators, and the
numeric_limits::has_denorm and numeric_limits::has_denorm_loss static
data members.
The std/ranges/iota/max_size_type.cc test doesn't get warnings for using
numeric_limits::has_denorm{,_loss} because of PR c++/125406. If that
gets fixed, we'll need two new dg-warning lines in that test.
libstdc++-v3/ChangeLog:
* doc/xml/manual/evolution.xml: Document deprecations.
* doc/html/manual/api.html: Regenerate.
* include/bits/max_size_type.h (numeric_limits::has_denorm):
Mark as deprecated.
(numeric_limits::has_denorm_loss): Likewise.
* include/std/limits (float_denorm_style): Mark as deprecated.
(numeric_limits::has_denorm, numeric_limits::has_denorm_loss):
Mark as deprecated.
* testsuite/18_support/numeric_limits/char16_32_t.cc: Add
dg-warning for expected deprecation warnings.
* testsuite/18_support/numeric_limits/char8_t.cc: Likewise.
* testsuite/18_support/numeric_limits/denorm_min.cc: Likewise.
* testsuite/18_support/numeric_limits/dr559.cc: Likewise.
* testsuite/18_support/numeric_limits/requirements/constexpr_data.cc:
Likewise.
* testsuite/18_support/numeric_limits/specialization_default_values.cc:
Likewise.
* testsuite/std/ranges/iota/max_size_type.cc: Likewise.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Martin Jambor [Thu, 21 May 2026 12:05:18 +0000 (14:05 +0200)]
ipa-cp: Adjust general IPA-CP cloning heuristics
This winter I have had a long look at the effects of different values
of parameter param_ipa_cp_eval_threshold on performance on SPEC 2017
and on how they affect code size - and how quickly we reach growth
size limit in param_ipa_cp_unit_growth - when compiling these
benchmarks bit also, cc1 in an -O3 bootstrap and clang.
After going through the numbers, it turns out that we tend to clone a
bit too much and especially that we hit the overall growth limit way
too quickly. As a result this patch does two things. First, it
raises the heuristics cost/benefit threshold to 1100 (from 500) which
is the value at which I started to see cloning benefits.
Second, it reverts a recent change to get_max_overall_size where the
size limit also depended on the current call-graph sweep. We only
want the threshold to gradually come down (now to 1100), not the size
constraints also, it turned out to defeat the initial purpose.
gcc/ChangeLog:
2026-04-07 Martin Jambor <mjambor@suse.cz>
* ipa-cp.cc (get_max_overall_size): Remove parameter CUR_SWEEP and
its use.
(decide_about_value): Adjust the call to get_max_overall_size.
(decide_whether_version_node): Likewise.
* params.opt (param_ipa_cp_eval_threshold): Initialize to 1100.
libgomp/ChangeLog:
2026-04-07 Martin Jambor <mjambor@suse.cz>
* testsuite/libgomp.c/ipcp-cb-spec1.c: Set lower param
ipa-cp-eval-threshold.
gcc/testsuite/ChangeLog:
2026-04-07 Martin Jambor <mjambor@suse.cz>
* gcc.dg/ipa/ipa-5.c: Adjust dump.
* gcc.dg/independent-cloneids-1.c: Set lower param
ipa-cp-eval-threshold.
* gcc.dg/vla-1.c: Likewise.
* g++.dg/ipa/devirt-2.C: Add an extra caller of the to-be-cloned
function.
riscv-toolchain-conventions PR #156 defines separate alignment
policies for RV32 Zilsd/Zclsd doubleword memory accesses. Add
-mzilsd-word-align and -mzilsd-strict-align to let users select
the word-aligned and naturally aligned variants explicitly.
Keep the existing -mstrict-align family in the same last-option-wins
option group so code can opt in or out without depending on option
order surprises. When a 2 * XLEN access is not allowed by the
selected policy, expand through scalar bit-field helpers instead of
selecting Zilsd loads or stores.
gcc/ChangeLog:
* common/config/riscv/riscv-common.cc (riscv_handle_option):
Handle Zilsd alignment options and clear the Zilsd-specific
explicit marker for -mstrict-align.
* config/riscv/riscv-opts.h (riscv_zilsd_align_type): New enum.
* config/riscv/riscv-protos.h
(riscv_expand_zilsd_misaligned_move): Declare as void.
(riscv_zilsd_valid_mem_p): Declare.
* config/riscv/riscv.cc (riscv_zilsd_required_align): New
functions.
(riscv_zilsd_valid_mem_p): New function.
(riscv_rtx_costs): Honor Zilsd alignment policy.
(riscv_split_64bit_move_p): Split invalid Zilsd GPR accesses.
(riscv_expand_zilsd_misaligned_move): New function.
(riscv_can_inline_p): Check effective Zilsd alignment policy.
(riscv_override_options_internal): Reject explicit Zilsd
alignment options for RV64.
* config/riscv/riscv.md (movmisaligndi): New expander.
(movmisaligndf): New expander.
* config/riscv/riscv.opt: Add -mzilsd-word-align and
-mzilsd-strict-align.
* config/riscv/riscv.opt.urls: Regenerate.
* doc/invoke.texi: Document the new options.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/zilsd-align-default-1.c: New test.
* gcc.target/riscv/zilsd-align-df-1.c: New test.
* gcc.target/riscv/zilsd-align-rv64-1.c: New test.
* gcc.target/riscv/zilsd-align-rv64-2.c: New test.
* gcc.target/riscv/zilsd-align-rv64-3.c: New test.
* gcc.target/riscv/zilsd-align-rv64-4.c: New test.
* gcc.target/riscv/zilsd-align-word-1.c: New test.
* gcc.target/riscv/zilsd-align-word-2.c: New test.
* gcc.target/riscv/zilsd-align-word-3.c: New test.
* gcc.target/riscv/zilsd-align-word-4.c: New test.
* gcc.target/riscv/zilsd-align-word-5.c: New test.
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
RISC-V C API pull request #183 specifies macros that let users
detect compiler support for intrinsic APIs independent of -march:
https://github.com/riscv-non-isa/riscv-c-api-doc/pull/183
Define __riscv_intrinsic_<extension> macros in the corresponding
RISC-V intrinsic headers. The macros describe compiler support for
an intrinsic API and do not depend on whether the related ISA
extension is enabled by -march.
Derive scalar composite macros from their component macros so they
are only defined when all component intrinsic headers have been
included.
gcc/testsuite/
* gcc.target/riscv/intrinsic-detection-bitmanip.c: New test.
* gcc.target/riscv/intrinsic-detection-crypto.c: New test.
* gcc.target/riscv/intrinsic-detection-scalar-reverse.c: New test.
* gcc.target/riscv/intrinsic-detection-scalar.c: New test.
* gcc.target/riscv/rvv/base/intrinsic-detection.c: New test.
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
RISC-V: Add C API and hwprobe feature bit for zicfiss
riscv-c-api-doc PR #187 defines the RISC-V C API feature bit
for zicfiss as group 1, bit 27. GCC already supports zicfiss,
so add the missing feature-bit metadata and libgcc copy of the
definition.
Upstream Linux exposes zicfiss through RISCV_HWPROBE_KEY_IMA_EXT_1.
Copy the upstream Linux hwprobe constants and map the zicfiss bit
directly to the matching feature bit.
This patch only adds metadata and runtime feature-bit probing. It
does not add ISA extension support.
gcc/ChangeLog:
* common/config/riscv/riscv-ext-bitmask.def: Add zicfiss.
* config/riscv/riscv-ext.def: Add C API bit position for
zicfiss.
libgcc/ChangeLog:
* config/riscv/feature_bits.c (ZICFISS_GROUPID,
ZICFISS_BITMASK, RISCV_HWPROBE_KEY_IMA_EXT_1,
RISCV_HWPROBE_EXT_ZICFISS): Define.
(SET_FROM_IMA_EXT_1): Define.
(__init_riscv_features_bits_linux): Query IMA_EXT_1 and set
zicfiss from the corresponding upstream Linux hwprobe bit.
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
RISC-V: Add Linux hwprobe mappings for existing extensions
Upstream Linux defines hwprobe bits in RISCV_HWPROBE_KEY_IMA_EXT_0
for the following extensions: supm, zicntr, zihpm, zfbfmin, zvfbfmin,
zvfbfwma, zicbom, zaamo, zalrsc, zabha, zalasr, zicbop, zilsd, zclsd,
and zicfilp.
GCC already supports these extensions, and previous patches add the
matching C API feature-bit metadata. Copy the upstream Linux bit
assignments and map them directly to the matching feature bits.
This patch does not synthesize summary or implied extension bits, and
it does not add new ISA support. The PR #185 feature bits depend on
riscv-c-api-doc PR #185.
libgcc/ChangeLog:
* config/riscv/feature_bits.c (RISCV_HWPROBE_EXT_SUPM,
RISCV_HWPROBE_EXT_ZICNTR, RISCV_HWPROBE_EXT_ZIHPM,
RISCV_HWPROBE_EXT_ZFBFMIN, RISCV_HWPROBE_EXT_ZVFBFMIN,
RISCV_HWPROBE_EXT_ZVFBFWMA, RISCV_HWPROBE_EXT_ZICBOM,
RISCV_HWPROBE_EXT_ZAAMO, RISCV_HWPROBE_EXT_ZALRSC,
RISCV_HWPROBE_EXT_ZABHA, RISCV_HWPROBE_EXT_ZALASR,
RISCV_HWPROBE_EXT_ZICBOP, RISCV_HWPROBE_EXT_ZILSD,
RISCV_HWPROBE_EXT_ZCLSD, RISCV_HWPROBE_EXT_ZICFILP): Define.
(__init_riscv_features_bits_linux): Set feature bits from the
corresponding upstream Linux hwprobe bits.
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
RISC-V: Add C API feature bits from riscv-c-api-doc PR #185
Add RISC-V C API feature bit metadata for these extensions from
riscv-c-api-doc PR #185: supm, zicntr, zihpm, zfbfmin, zvfbfmin,
zvfbfwma, zicbom, zaamo, zalrsc, zabha, zalasr, zicbop, and zicfilp.
This patch only adds metadata. It does not add ISA extension
support or new runtime probing.
gcc/ChangeLog:
* common/config/riscv/riscv-ext-bitmask.def: Add supm,
zicntr, zihpm, zfbfmin, zvfbfmin, zvfbfwma, zicbom,
zaamo, zalrsc, zabha, zalasr, zicbop, and zicfilp.
* config/riscv/riscv-ext.def: Add C API bit positions for
supm, zicntr, zihpm, zfbfmin, zvfbfmin, zvfbfwma,
zicbom, zaamo, zalrsc, zabha, zalasr, zicbop, and
zicfilp.
RISC-V: Add C API feature bits for existing extensions
The RISC-V C API already allocates feature bits for b, e, h,
zilsd, zclsd, zcmp, zifencei, and zmmul. GCC already has
these extensions in riscv-ext.def, but the FMV bitmask table and
the libgcc copy of the bit definitions did not include them.
This patch only adds metadata. It does not add ISA extension
support.
gcc/ChangeLog:
* common/config/riscv/riscv-ext-bitmask.def: Add b, e, h,
zilsd, zclsd, zcmp, zifencei, and zmmul.
Jonathan Wakely [Wed, 1 Apr 2026 22:45:03 +0000 (23:45 +0100)]
libstdc++: Restore allocator constructor for std::packaged_task (P3503R3)
WG21 approved P3503R3 (by me and Nicolas Morales) in Sofia, 2025. The
change is to make std::promise and std::packaged_task be constructible
with an allocator, but not to support general uses-allocator
construction. So they do not have specializations of std::uses_allocator
and do not have an allocator-extended version of every normal
constructor (i.e., no allocator-extended move constructors and for
std::packaged_task, no allocator-extended default constructor).
Since the changes were originally proposed as resolutions to LWG 2095
and LWG 3003, this treats the change as a DR for all standard versions
from C++11 up. This means the constructor semantics are consistent (and
sensible) for all standard versions.
Because I pre-emptively implemented the original resolution of LWG 2095
(in r0-112872-g376d7c51ece6f8), we need to remove the allocator-extended
constructors of std::promise and std::packaged_task which I added but
which are not in the working draft after the P3503R3 changes.
To restore the packaged_task(allocator_arg_t, const Alloc&, F&&)
constructor that was removed by LWG 2921 we just need to remove the #if
that disabled it for C++17 and later.
Finally, we need to remove the std::uses_allocator partial
specialization for std::promise (removed by P3503R3) and the one for
std::packaged_task (already disabled for C++17 and later by LWG 2976).
libstdc++-v3/ChangeLog:
* doc/xml/manual/evolution.xml: Document constructor changes.
* doc/html/*: Regenerate.
* include/std/future (uses_allocator): Remove specializations
for std::promise and std::packaged_task.
(promise(allocator_arg_t, const Alloc&, promise&&)): Remove
constructor proposed for LWG 2095 but not in P3503R3.
(packaged_task(allocator_arg_t, const Alloc&)): Likewise.
(packaged_task(allocator_arg_t, const Alloc&, packaged_task&&)):
Likewise.
(packaged_task(allocator_arg_t, const Alloc&, F&&)): Restore
constructor for C++20 and later.
* testsuite/30_threads/packaged_task/uses_allocator.cc: Adjust
expected result for static_assert.
* testsuite/30_threads/promise/uses_allocator.cc: Likewise.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Tomasz Kamiński [Fri, 24 Apr 2026 03:25:59 +0000 (05:25 +0200)]
libstdc++: Support integer-class sized range in inplace_vector.
Simply cast size of the input range to size_t, after verifying that
it fits in remaining capacity, and thus in size_t.
libstdc++-v3/ChangeLog:
* include/std/inplace_vector (inplace_vector::assign_range)
(inplace_vector::append_range): Cast ranges::distance(__rg)
to size_t.
* testsuite/23_containers/inplace_vector/cons/from_range.cc: New
test for ranges with integer-class size_type.
* testsuite/23_containers/inplace_vector/modifiers/assign.cc:
Likewise.
* testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc:
Likewise.
Reviewed-by: Patrick Palka <ppalka@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
Xi Ruoyao [Mon, 18 May 2026 14:59:33 +0000 (22:59 +0800)]
LoongArch: Rename rbit<mode> to bitreverse<mode>2 [PR 50481]
r17-523 has added the __builtin_bitreverse{8,16,32,64} builtins and
established that the standard optab names for them are
bitreverse<mode>2. Rename the rbit<mode> expanders so they'll be used
for those builtins.
r17-567 has already removed the uses of rbit<mode> so the old names do
not need to be kept.
PR target/50481
gcc/
* config/loongarch/loongarch.md (@rbit<GPR:mode>2): Rename to
...
(@bitreverse<mode>2): ... this.
(rbithi2): Rename to ...
(bitreversehi2): ... this.
(rbitqi2): Rename to ...
(bitreverseqi2): ... this.
(rbitsi_extended): Rename to ...
(bitreversesi2_extended): ... this.
gcc/testsuite/
* gcc.target/loongarch/la64/bitreverse.c: New test.
Pietro Monteiro [Wed, 20 May 2026 23:33:35 +0000 (19:33 -0400)]
algol68: Add FLOOR as synonym for ENTIER
The Revised Report{10.2.3.4.r} specifies ENTIER as the monadic
operator that yields the greatest integral value less than or equal to
a real value (i.e., rounds toward negative infinity).
Many programming languages call this operator FLOOR. Add FLOOR as a
synonym for ENTIER to allow use of the familiar name; no semantic
change is introduced.
gcc/algol68/ChangeLog:
* a68-parser-prelude.cc (gnu_prelude): Map FLOOR(L real):L int
to ENTIER(L real):L int.
* ga68.texi: Add a section for real operators in the Extended
prelude chapter and document FLOOR.
gcc/testsuite/ChangeLog:
* algol68/execute/entier-1.a68: Add test for FLOOR = ENTIER.
* algol68/compile/floor-1.a68: New test.
Bootstrapped and regression tested on aarch64-linux-gnu with
RUNTESTFLAGS="tree-ssa.exp".
Changes since v1:
* v5: Split testcase into bool, integral, short and float-specific
files.
* v4: Moved match rule to right place alongside other
simple_comparison narrowing cases.
* v3: Simplify match rule.
Add more cases in test file.
* v2: Generalize the match rule to generic narrowing
integral equality comparisons from bool equality.
PR tree-optimization/112533
gcc/ChangeLog:
* match.pd: Add integral narrowing eq/ne to XOR-against-zero
rule for (T)(x) == (T)(y) where precision(T) < precision(x).
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/narrow-bool-eq.c: New test.
* gcc.dg/tree-ssa/narrow-integral-eq.c: New test.
* gcc.dg/tree-ssa/narrow-short-eq.c: New test.
* gcc.dg/tree-ssa/narrow-float-eq.c: New test.
Thomas Koenig [Wed, 20 May 2026 20:43:10 +0000 (22:43 +0200)]
PR fortran/106546 - inline matmul with -fno-automatic
There was a problem caused with allocatable arrays used for
front-end optimization when -fno-automatic was specified.
Solved by explicitly setting the automatic attribute on the
symbol. It required "-O2 -fcheck=bounds -fno-automatic"
to be seen.
gcc/fortran/ChangeLog:
PR fortran/106546
* frontend-passes.cc (create_var): Set attr->automatic on
new symbol.
(create_do_loop): Likewise on iteration variable.
gcc/testsuite/ChangeLog:
PR fortran/106546
* gfortran.dg/inline_matmul_27.f90: New test.
The previous patch removed the only caller of references_value_p
to want the only_useless behaviour. This patch therefore removes
that parameter and converts the function to an iterator.
I don't have numbers to show that using an iterator is better after the
previous patch. But converting to an iterator was the first low-hanging
fruit that I tried for the insn-extract.cc slowness, at a time when
references_value_p accounted for over 50% of compile time on aarch64.
It made a significant difference then.
When bootstrapping with RTL checking enabled, a lot of the
compile time for insn-extract.cc is spent in var-tracking
(~75% on cfarm425, an aarch64 box, and ~42% on my local x86 box).
The top of the aarch64 profile is:
var-tracking uses cselib to track equivalences between values.
However, whereas most cselib passes clear the tables after each
bb/ebb, var-tracking instead retains invariant values for the
whole function. It does this by arranging for invariant values
to be moved from the main hash table to cselib_preserved_hash_table.
cselib_preserved_hash_table is then the first table that is consulted
during a lookup (cselib_find_slot). This allows new non-invariant
locations to be added to an entry of cselib_preserved_hash_table.
These non-invariant locations might be invalidated later, in the
usual way.
At the end of each block, cselib_preserve_only_values invalidates all
registers and memory. It then goes through cselib_preserved_hash_table
to remove locations that have become useless through invalidation.
This never makes a whole value useless, because the invariant
locations still hold.
The issue in insn-extract.cc is that we have many blocks and soon
have many entries in cselib_preserved_hash_table. Very few of those
entries are used in each block, but every location of every entry is
examined after each block.
This patch adds a bit to cselib_val to say whether every location only
references preserved values, and thus will never have useless locations
in its current form. The patch then uses this information to maintain
a list of entries in cselib_preserve_only_values that might have useless
locations. remove_useless_values can then iterate over this list instead
of the whole hash table.
This required finding space for two new bits in cselib_val. Since there
are no holes, I ended up stealing two bits from the hash.
On cfarm425, the effect is to go from:
variable tracking : 709.47 ( 75%) 35M ( 1%)
to:
variable tracking : 1.08 ( 0%) 35M ( 1%)
There was no change to the final object file.
gcc/
* cselib.h (cselib_val::HASH_MASK): New static constant.
(cselib_val::hash): Turn into a 30-bit bitfield.
(cselib_val::in_preserved_table_p): New bitfield.
(cselib_val::all_locs_preserved_p): Likewise.
* cselib.cc: Include rtl-iter.h.
(cselib_preserved_prune_list): New variable.
(cselib_clear_all_locs_preserved): New function.
(new_elt_loc_list): Call it when modifying a value's location list.
(preserve_constants_and_equivs): Set in_preserved_table_p when
moving a value to the preserved hash table. Also push such values
onto cselib_preserved_prune_list.
(cselib_find_slot): Mask out the upper 2 bits of the hash.
(discard_useless_locs): New overload, split out from original
hash table traverse callback. Use an inline rtl iteration
instead of calling references_value_p. Record whether the
retained location only reference preserved value.
(remove_useless_values): Iterate over cselib_preserved_prune_list
instead of the hash table itself. Remove a value from the list
if all remaining locations only reference preserved value.
(new_cselib_val): Initialize the new bitfields.
(cselib_finish): Free cselib_preserved_prune_list.
This is a very minor and perhaps personal change, but when looking at
new_elt_loc_list, I was constantly distracted by the fact that one of
the values is accessed directly ("val") and the other is accessed
indirectly ("CSELIB_VAL_PTR (loc)").
This patch caches the result of CSELIB_VAL_PTR so that all updates
are done on direct cselib_val pointers. It should also be a minor
optimisation, especially when RTL checking is enabled.
David Malcolm [Wed, 20 May 2026 14:24:40 +0000 (10:24 -0400)]
testsuite: add some libstdc++ -fanalyzer test coverage (PR 125236)
This patch adds some test coverage for -fanalyzer's handling of
basic usage of libstdc++ to g++.dg/analyzer/torture, providing
end-to-end testing of the interaction of -fanalyzer and libstdc++ at
various optimization levels.
Currently this is rather minimal (to ensure the tests pass).
I'm working on debugging -fanalyzer issues with other usage patterns
and hope to extend this further as more start working.
gcc/testsuite/ChangeLog:
PR analyzer/125236
* g++.dg/analyzer/torture/README.txt: New.
* g++.dg/analyzer/torture/std-string-ctor-large-literal.C: New
test.
* g++.dg/analyzer/torture/std-string-ctor-small-literal.C: New
test.
* g++.dg/analyzer/torture/std-string-default-ctor.C: New test.
* g++.dg/analyzer/torture/std-unique-ptr-1.C: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
David Malcolm [Wed, 20 May 2026 12:52:29 +0000 (08:52 -0400)]
testsuite: add reduced test for -fanalyzer on std::string [PR125304]
The pointer comparison bug that led to false positives from -fanalyzer
on std::string (by confusing the small-string-optimization and
heap-allocation branches) should be fixed by r17-609-g573b66baa6cb8d.
Add a torture test for this, based on a reduced snapshot of libstdc++,
after preprocessing, with _M_is_local() made public so that we can test
this directly.
gcc/testsuite/ChangeLog:
PR analyzer/125304
* g++.dg/analyzer/torture/std-string-pr125304.C: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Jonathan Wakely [Tue, 19 May 2026 15:13:15 +0000 (16:13 +0100)]
libstdc++: Use #embed for static tzdata.zi file
This doesn't make much difference to the time taken to compile tzdb.cc
but it is simpler and more maintainable than generating a header in the
makefile.
libstdc++-v3/ChangeLog:
* src/c++20/Makefile.am [USE_STATIC_TZDATA]: Remove targets for
tzdata.zi.h, tzdb.lo and tzdb.o.
* src/c++20/Makefile.in: Regenerate.
* src/c++20/tzdb.cc (tzdata_chars): Use #embed.
(tzdata_stream::ispanbuf): Remove adjustment for extra newline
inserted by the Makefile recipe for tzdata.zi.h.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Uros Bizjak [Thu, 14 May 2026 16:38:46 +0000 (18:38 +0200)]
i386: Remove TARGET_SHIFT1 tuning feature
All supported versions of GNU as automatically encode "sal $1, reg"
using the shorter implicit-count-1 form (opcode D1), making the
compiler-side i486 TARGET_SHIFT1 / X86_TUNE_SHIFT1 logic redundant.
Remove the tuning feature and simplify all affected shift instruction
patterns by unconditionally emitting the explicit-immediate form and
relying on the assembler to produce the optimal encoding. Update the
length_immediate attributes accordingly to report 0 for const-1 shift
counts, correctly reflecting the assembled output.
Michiel Derhaeg [Wed, 20 May 2026 07:57:09 +0000 (10:57 +0300)]
arc: check if the addend fits when referencing small data memory [PR115650]
This prevents linker errors when referencing small data using large
offsets. In practice it is very unlikely to be a real problem but this
was fixed because other compilers do this check and it ensures the
following tests now succeed:
- gcc.dg/torture/pr60115.c
- gcc.dg/torture/pr105665.c
Jakub Jelinek [Wed, 20 May 2026 07:18:15 +0000 (09:18 +0200)]
i386: Fix up peephole2s with const359_operand [PR125373]
The following testcase ICEs, because the const359_operand peephole2s
optimize multiplication of %rsp by 5 (or could by 3 or 9) into a lea.
Which is not valid, because sp is not a valid index register.
The following patch makes sure to use index_reg_operand predicate instead
so that it won't match for the stack pointer.
2026-05-20 Jakub Jelinek <jakub@redhat.com>
PR target/125373
* config/i386/i386.md
(Convert imul by three, five and nine into lea define_peephole2s): Use
index_reg_operand instead of register_operand.
libstdc++-v3/Changelog:
* config/abi/pre/gnu.ver: Remove recent symbol swept up in
GLIBCXX_3.4.21.
* include/bits/basic_string.tcc (reserve): Guard __limit decl
under #if __cpp_exceptions to quiet warning.
Jakub Jelinek [Wed, 20 May 2026 06:49:06 +0000 (08:49 +0200)]
i386: Use vpaddq + vpermilpd for some non-const permutations [PR125357]
On Tue, May 19, 2026 at 10:30:16AM +0200, Jakub Jelinek wrote:
> On Tue, May 19, 2026 at 10:51:37AM +0300, Alexander Monakov wrote:
> > Thanks for looking at the issue, I really appreciate it. The same problem
> > exists with 64-bit lanes (V2DF/V2SI modes, we fail to utilize vpermilpd).
>
> The control in that case is in bits 1 and 65 rather than 0 and 64.
> So, in order to use vpermilpd for
> __builtin_shuffle (v2di_or_v2df, v2di);
> one would need to first shift the mask (or vpaddq with itself).
> Though, that is still shorter than what we emit right now.
PR target/125357
* config/i386/i386-expand.cc (ix86_expand_vec_perm): For TARGET_AVX
one_operand_shuffle handle also V2DImode and V2DFmode using
vpaddq and vpermilpd.
* gcc.target/i386/avx-pr125357-2.c: New test.
* gcc.target/i386/avx2-pr125357-2.c: New test.
liuhongt [Mon, 5 Jan 2026 02:52:23 +0000 (18:52 -0800)]
Limit outer-loop unswitching by duplicated code size
When unswitching predicates from the innermost loop, hoisting the
unswitch out to an outer loop duplicates only the outer-loop bodies;
the innermost loop is shared. Estimate the cost as
candidate_size - innermost_size and stop selecting an outer loop once
that exceeds param_max_unswitch_insns. innermost_size is hoisted out
of the walk so estimate_loop_insns is called once per level.
gcc/ChangeLog:
* tree-ssa-loop-unswitch.cc (estimate_loop_insns): New function.
(init_loop_unswitch_info): Do not select an outer loop for
unswitching when the duplicated outer-body size exceeds
param_max_unswitch_insns.
Zhou Qiankang [Mon, 18 May 2026 08:03:02 +0000 (16:03 +0800)]
LoongArch: Fix missing plugin header for cpu-features.h [PR125362]
When compiling GCC plugins that include target headers on LoongArch,
the build fails because cpu-features.h is not installed during
`make install-plugin`. The header, included by loongarch-protos.h,
was not listed in any variable that feeds PLUGIN_HEADERS. Add it to
TM_H, following the same approach used by i386 for i386-cpuinfo.h.
Kito Cheng [Tue, 19 May 2026 10:33:52 +0000 (18:33 +0800)]
testsuite: Update CRC dump scan regex for reversed crc table
Before r17-567 ("middle-end: Optimize reversed CRC table-based
implementation"), a reversed CRC without a crc_rev optab was
expanded as: reflect the input, run the non-reversed CRC table,
then reflect the result. So the table that got emitted was the
non-reversed one, and the dump printed:
;; emitting crc table crc_<N>_polynomial_<P> ...
After that patch, the middle end builds a reversed CRC table
directly and the dump prints:
Any target without a crc_rev optab hits the new path. For example,
RISC-V's bitmanip.md defines crc_rev<ANYI1:mode><ANYI:mode>4 with
no TARGET_ guard, so the optab is always there and the dump still
says "using optab for ..." -- the test passes. But x86's
crc_rev<SWI124:mode>si4 needs TARGET_CRC32, so a default x86 build
(no SSE4.2 / -march=cascadelake) has no optab, falls back to the
table, and prints the new "emitting reversed crc table" message.
The old regex only accepted "emitting crc table", so x86 fails.
These tests only call __builtin_rev_crc*, which always take the
reversed path, so the non-reversed "emitting crc table" message
cannot appear here. Just replace it with the new wording.
gcc/testsuite/ChangeLog:
* gcc.dg/crc-builtin-rev-target32.c: Match the new
"emitting reversed crc table" dump message.
* gcc.dg/crc-builtin-rev-target64.c: Likewise.
David Malcolm [Tue, 19 May 2026 19:04:30 +0000 (15:04 -0400)]
analyzer: fix pointer comparisons [PR125304]
PR analyzer/125304 describes a false positive from -fanalyzer on a
trivial use of std::string, due to the analyzer getting confused
about the paths for the small-string optimization versus heap-allocated
strings.
The root cause is a bug in region_svalue::eval_condition which handles
many kinds of pointer comparison, but which seems to have often been
hidden by the optimizer. Previously, it simply compared for identity
of the underlying "region" instance, returning true if identical, false
otherwise. This is wrong:
(a) for some cases, including the above one, different "region" instances
might represent the same memory (and thus we were returning "false" when
we should have returned "true")
(b) for some cases, different "region" instances we might not be able to
determine if they are the same address (and thus we were returning "false"
when we should have returned "unknown")
This patch rewrites region_svalue::eval_condition so that rather than
comparing the regions by identity, it compares their region_offset
values, taking into account their base regions and byte offsets within
those regions. Doing so requires using store::eval_alias, and so the
patch extends that to handle more cases precisely.
This new implementation fixes (a) and (b) above. There are some cases
where precision could be improved (where with the patch we return "unknown"
when we ought to return a known bool), but fixing these would be more
invasive and so are left to followup work.
gcc/analyzer/ChangeLog:
PR analyzer/125304
* common.h (compare_bit_offsets_p): New decl.
(eval_region_offset_comparison): New decl.
* region-model.cc (region_model::on_assignment): Pass *this to
store::set_value to help determination of aliasing.
(region_model::set_value): Likewise.
(region_model::eval_condition): Likewise for
region_svalue::eval_condition.
* region.cc (compare_bit_offsets_p): New.
(region_offset::dump_to_pp): Dump the base region, wrapping the
whole thing in braces.
(eval_byte_offset_comparison): New.
(eval_region_offset_comparison): New.
* store.cc (store::set_value): Add "model" param and pass it to
eval_alias.
(store::eval_alias): Add "model" param and pass to eval_alias_1.
Add early return of true when checking a base region against
itself. Replace final return of "unknown" with logic that
compares the kinds of the two base regions, and may be able
to return "false" rather than "unknown".
(store::eval_alias_1): Add "model" param and pass to eval_alias.
Assert that we have two different base_regions.
(store::replay_call_summary_cluster): Pass model to set_value.
* store.h (store::set_value): Add "model" param.
(store::eval_alias): Likewise.
(store::eval_alias_1): Likewise.
* svalue.cc (region_svalue::eval_condition): Likewise.
Reimplement in terms of eval_region_offset_comparison.
* svalue.h (region_svalue::eval_condition): Add "model" param.
gcc/testsuite/ChangeLog:
PR analyzer/125304
* c-c++-common/analyzer/pointer-comparison-pr125304-eq.c: New test.
* c-c++-common/analyzer/pointer-comparison-pr125304-ge.c: New test.
* c-c++-common/analyzer/pointer-comparison-pr125304-gt.c: New test.
* c-c++-common/analyzer/pointer-comparison-pr125304-le.c: New test.
* c-c++-common/analyzer/pointer-comparison-pr125304-lt.c: New test.
* g++.dg/analyzer/pointer-casts-pr125304.C: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>