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 {}.
Eric Botcazou [Fri, 31 Jul 2026 18:18:15 +0000 (20:18 +0200)]
Ada: Fix bogus error for 'Value invoked on function call and -gnatVa
This happens when the function takes an In Out or Out parameter, so only in
Ada 2012 and later. The mechanism used to implement the validity check for
the call, required by -gnatVa, inserts the copy-out statement incorrectly.
gcc/ada/
PR ada/126379
* exp_ch6.adb (Insert_Post_Call_Actions): Also deal with attribute
references as parent node.
gcc/testsuite/
* gnat.dg/validity_check3.adb: New test.
Patrick Palka [Fri, 31 Jul 2026 18:56:29 +0000 (14:56 -0400)]
libstdc++: Optimize ranges::distance for segmented iterators [PR123211]
For segmented iterators, ranges::distance is equivalent to the sum of
ranges::distance of each of its segments.
PR libstdc++/123211
libstdc++-v3/ChangeLog:
* include/bits/ranges_base.h (__distance_fn::operator()): For
the non-sized-sentinel overload, recursively handle segmented
iterators via __for_each_segment.
Patrick Palka [Fri, 31 Jul 2026 18:54:12 +0000 (14:54 -0400)]
libstdc++: Introduce segmented iterator concept and traversal
This patch defines a new utility function std::__for_each_segment for
iterating over "segmented" iterators, i.e. iterators for ranges composed
of sub-ranges. Such iterators must provide a static member function
_S_for_each_segment implementing traversal over their segments via a
callback function. This patch implements such traversal for iterators
of std::deque, ranges::join_view and ranges::concat_view.
PR libstdc++/123211
libstdc++-v3/ChangeLog:
* include/bits/stl_deque.h (_Deque_iterator::_S_for_each_segment):
Define.
(_Deque_iterator::_S_enable_for_each_segment): Define.
* include/bits/stl_iterator_base_funcs.h: Include <bits/move.h>.
(__for_each_segment): Define.
* include/bits/stl_iterator_base_types.h: Include
<ext/type_traits.h> in C++98 mode.
(__enable_for_each_segment): Define.
(__segmented_iterator): Define in C++20.
* include/debug/safe_iterator.h
(_Safe_iterator::_S_for_each_segment): Define.
(_Safe_iterator::_S_enable_for_each_segment): Define.
* include/std/ranges (join_view::_Iterator::_Iterator): New
constructor taking both an inner and outer iterator.
(join_view::_Iterator::_S_for_each_segment): Define.
(join_view::_Iterator::_S_enable_for_each_segment): Define.
(concat_view::_Iterator::_S_for_each_segment): Define.
(concat_view::_Iterator::_S_enable_for_each_segment): Define.
* testsuite/23_containers/deque/for_each_segment.cc: New test.
* testsuite/std/ranges/adaptors/join/for_each_segment.cc: New test.
* testsuite/std/ranges/concat/for_each_segment.cc: New test.
Patrick Palka [Fri, 31 Jul 2026 18:11:42 +0000 (14:11 -0400)]
libstdc++: Implement LWG 4440 feature-test macros added to <iosfwd>
Note __cpp_lib_char8_t doesn't use the <bits/version.h> mechanism, it's
defined in c++config and thus provided by all headers by default.
libstdc++-v3/ChangeLog:
* include/std/iosfwd: Provide feature-test macros
__cpp_lib_spanstream and __cpp_lib_syncbuf.
* testsuite/27_io/headers/iosfwd/synopsis.cc: Verify values
of these FTMs.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Patrick Palka [Fri, 31 Jul 2026 18:11:38 +0000 (14:11 -0400)]
libstdc++: Implement LWG 4301 changes to condition_variable{_any}
* include/std/condition_variable (condition_variable::wait_until):
Take timeout parameter by value as per LWG 4301.
(condition_variable::wait_for): Likewise.
(condition_variable::__wait_until_impl): Likewise.
(condition_variable_any::wait_until): Likewise.
(condition_variable_any::wait_for): Likewise.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Paul Thomas [Fri, 24 Jul 2026 14:05:46 +0000 (15:05 +0100)]
Fortran: Auto deallocate coarrays, allocated in team blocks [PR126205]
Gfortran was not compliant with F2018(11.1.5.2), which requires that
coarrays that are allocated within a team block are deallocated immediately
before END TEAM.
This the fourth variant of the patch; the main differences being whether
the code is located on resolve.cc, split between resolve.cc and
trans-stmt.cc or, as here, split between parse.cc, match.cc and st.cc.
The main attraction of the latter scheme is that coarray.cc and
resolve.cc do the main job of preparing the code for translation.
The team context is tracked using a vector of team namespaces, which is
pushed at CHANGE TEAM and popped at END TEAM. The allocate expressions
are stashed in a vector hash_map, keyed on the namespace. The allocate
expressions are stored while the ALLOCATE statments are being matched.
They are then recovered before end in parse_change_team and sent off
for automatic deallocation in st.cc(deallocate_allocated_coarrays.
The use of st.cc for functions generating chunks of code is a pointer
to something that I have been eyeing for a long time, which is to
extract all such functions from class.cc and resolve.cc so that they
can be refactored to use common chunks. This, however, is for another
time!
2026-07-24 Paul Thomas <pault@gcc.gnu.org>
gcc/fortran
PR fortran/126205
* gfortran.h: Add prototype for deallocate_allocated_coarrays.
hash_map team_allocated_coarrays, vector team_context_stack and
prototype for get_current_team_context.
* match.cc (gfc_match_allocate): Capture allocate expressions
of allocatable coarrays and stash in team_allocated_coarrays.
* parse.cc (parse_change_team): Push team context. When end is
seen, create the code to deallocate allocated coarrays in this
context, using deallocate_allocated_coarrays.
* st.cc (get_guarded_dealloc): Generate code to produce
IF (ALLOCATED (expr)) DEALLOCATE (expr).
(deallocate_allocated_coarrays): Modify the final array ref of
the allocate expressions and call get_guarded_dealloc.
gcc/testsuite/
PR fortran/126205
* gfortran.dg/coarray/team_allocated_coarrays.f90: New test.
Andrea Pinski [Fri, 31 Jul 2026 04:06:31 +0000 (21:06 -0700)]
match: Fix min/max patterns for `((signed)a) < 0` [PR126458]
In r16-4585-ga4e033fb51d566, I accidently used the wrong type
to form SIGNED_TYPE_MIN. This was ok most of the time except
if the two types differ only by one precision. When they diff
by one precision, we would incorrectly detect the wrong thing
and think it should be a min/max. This fixes the problem
by using the precision of the constant (0) rather then the final
type.
Pushed as obvious after a bootstrap/test on x86_64-linux-gnu.
PR tree-optimization/126458
gcc/ChangeLog:
* match.pd (min/max detection): Fix precision of
the signed type min.
gcc/testsuite/ChangeLog:
* gcc.dg/torture/pr126458-1.c: New test.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Tomasz Kamiński [Fri, 31 Jul 2026 14:52:09 +0000 (16:52 +0200)]
libstdc++: Reject user-defined specializations for coroutine_handle.
The P0912R5, "Merge Coroutines TS into C++20 working draft" that
introduced them already included made specializing coroutine_handle
ill-formed, no diagnostic required.
This is QoI improvment, that produces diagnostic in such situation
by decaroting base template with [[_Clang::__no_specializations]].
libstdc++-v3/ChangeLog:
* include/std/coroutine: Ignore -Winvalid-specialization in file.
(std::coroutine_handle): Add clang::no_specializations attribute.
* testsuite/18_support/coroutines/specializations_neg.cc: New test.
Tomasz Kamiński [Wed, 29 Jul 2026 10:14:39 +0000 (12:14 +0200)]
libstdc++: Reject user-defined specializations for allocator traits.
Marks allocator_traits primary tempalte with [[_Clang::__no_specializations]]
attribute in C++23 or later.
This is QoI improvement for C++23 P2652R2, "Disallow User Specialization
of allocator_traits", that makes such cases ill-formed, but does not
require diagnostic.
Jonathan Wakely [Wed, 29 Jul 2026 18:04:37 +0000 (19:04 +0100)]
libstdc++: Make chrono::parse accept out-of-range values that aren't needed [PR126364]
When parsing a time with %R or %T we should ignore out of range hours
and minutes if the type being parsed doesn't need them, e.g. when
parsing a chrono::year_month_day from "2026-07-29 99:99:99" we do not
set failbit, and should continue parsing after the invalid hours and
minutes.
Because we were short circuiting as soon as we saw "99" (in either
field) we didn't parse to the end of the %R or %T field, and then could
set failbit if there were any subsequent characters or flags to parse.
The fix is to only short-circuit when setting failbit, and continue
parsing otherwise.
With this change, we no longer hit the 'break' when __read_unsigned(2)
returns -1 (e.g. because the input was non-numeric) unless we're
parsing a type that needs the %R or %T value. But that's OK, because
__read_unsigned sets failbit when it returns -1 and so the next
__read_chr or __read_unsigned will fail without extracting more
characters, and we'll break there instead. So there's no change in
observable behaviour for non-numeric inputs, only for out-of-range
numeric inputs.
libstdc++-v3/ChangeLog:
PR libstdc++/126364
* include/bits/chrono_io.h (_Parser::operator()) <R>: Only break
early when setting failbit.
* testsuite/std/time/parse/126364.cc: New test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Muhammad Kamran [Thu, 30 Jul 2026 17:34:19 +0000 (18:34 +0100)]
libgcc: aarch64: Do not use .previous after build attributes
.aeabi_subsection selects the current AArch64 build-attribute
subsection, not the current ELF section. The following .previous
therefore does not return from the build-attribute subsection. In
aarch64-asm.h it instead switches back to .note.GNU-stack, which was the
previous ELF section after emitting the non-executable stack note.
Remove the .previous from the build-attribute marking path. Keep it in
the GNU_PROPERTY path, where it matches the explicit switch to
.note.gnu.property.
libgcc/ChangeLog:
* config/aarch64/aarch64-asm.h (FEATURE_1_AND_MARK): Do not emit
.previous after AArch64 build attributes.
c++: ICE on on systems without mmap support [PR124806]
On systems without mmap support, cc1plus can crash when finishing module
output after earlier errors prevented elf_out::begin from running. In
that case elf_out::end attempts to fill in the ELF header even though
hdr.buffer was never initialized.
gcc/cp/ChangeLog:
PR c++/124806
* module.cc (elf_out::began): New data member.
(elf_out::begin): Set it after successful initialization.
(elf_out::end): Do not finalize output that never began.
Jakub Jelinek [Fri, 31 Jul 2026 07:11:08 +0000 (09:11 +0200)]
match.pd: Fix 2 further problems with narrow shift count types [PR126504]
This is the same problem as in just fixed PR126476, we have patterns
which simplify something involving a shift to comparison of the shift
count against a compile time determined value.
Like in PR126476, if the shift count has a very narrow type like
unsigned _BitInt(4) in the example and we want to compare it against
something that doesn't fit into that type (like 20), then we miscompile
it as comparison against something else (like 4), even when actually
it just means that for no valid value the original will ever be true
(resp. false), depending on what comparison it is.
Now, why we have 4 very similar simplifiers is weird, sure, the first
two changed in the last PR were one left shift and one right shift
and in both cases powers of two, but here we have two others which
look very similar, especially the last one to the first one.
2026-07-31 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/126504
* match.pd ((CST1 << A) == CST2 -> A == ctz (CST2) - ctz (CST1)):
If cand isn't representable in TREE_TYPE (@1), simplify to
cmp == NE_EXPR.
(((1 << n) & M) != 0 -> n == log2 (M)): Don't simplify if
log2 doesn't fit into TREE_TYPE (@0).
Jakub Jelinek [Fri, 31 Jul 2026 07:07:26 +0000 (09:07 +0200)]
bitintlower: Fix up handle_plus_minus [PR126503]
The following testcase is miscompiled on aarch64 (but not on x86_64).
The difference is that x86_64/i686 define optabs that make it use IFN_UADDC
and IFN_USUBC, those are then used both in the loop and to perform the
most significant limb, so
# _6 = PHI <0(2), _7(3)>
# _9 = PHI <0(2), _10(3)>
_8 = VIEW_CONVERT_EXPR<unsigned long[5]>(a)[_6];
_11 = .USUBC (0, _8, _9);
_12 = IMAGPART_EXPR <_11>;
_13 = REALPART_EXPR <_11>;
VIEW_CONVERT_EXPR<unsigned long[7]>(<retval>)[_6] = _13;
_14 = _6 + 1;
_15 = VIEW_CONVERT_EXPR<unsigned long[5]>(a)[_14];
_16 = .USUBC (0, _15, _12);
_10 = IMAGPART_EXPR <_16>;
_17 = REALPART_EXPR <_16>;
VIEW_CONVERT_EXPR<unsigned long[7]>(<retval>)[_14] = _17;
_7 = _6 + 2;
if (_7 != 4)
in the loop and
_18 = MEM <unsigned long> [(_BitInt(257) *)&a + 32B];
_19 = (<unnamed-signed:1>) _18;
_20 = (<unnamed-unsigned:1>) _19;
_21 = (unsigned long) _20;
_22 = .USUBC (0, _21, _10);
_23 = IMAGPART_EXPR <_22>;
_24 = REALPART_EXPR <_22>;
_25 = (<unnamed-signed:1>) _24;
_26 = (unsigned long) _25;
MEM <unsigned long> [(unsigned _BitInt(400) *)&<retval> + 32B] = _26;
...
after the loop. Now, on targets which don't support the optab, we instead
use
# _6 = PHI <0(2), _7(3)>
# _9 = PHI <0(2), _10(3)>
_8 = VIEW_CONVERT_EXPR<unsigned long[6]>(a)[_6];
_11 = .SUB_OVERFLOW (0, _8);
_13 = REALPART_EXPR <_11>;
_14 = IMAGPART_EXPR <_11>;
_15 = .SUB_OVERFLOW (_13, _9);
_16 = IMAGPART_EXPR <_15>;
_12 = _14 + _16;
_17 = REALPART_EXPR <_15>;
VIEW_CONVERT_EXPR<unsigned long[8]>(<retval>)[_6] = _17;
_18 = _6 + 1;
_19 = VIEW_CONVERT_EXPR<unsigned long[6]>(a)[_18];
_20 = .SUB_OVERFLOW (0, _19);
_21 = REALPART_EXPR <_20>;
_22 = IMAGPART_EXPR <_20>;
_23 = .SUB_OVERFLOW (_21, _12);
_24 = IMAGPART_EXPR <_23>;
_10 = _22 + _24;
_25 = REALPART_EXPR <_23>;
VIEW_CONVERT_EXPR<unsigned long[8]>(<retval>)[_18] = _25;
_7 = _6 + 2;
if (_7 != 4)
in the loop (i.e. instead of one .USUBC 2 .SUB_OVERFLOW) and then
after the loop for the most significant limb
_26 = MEM <unsigned long> [(_BitInt(257) *)&a + 32B];
_27 = (<unnamed-signed:1>) _26;
_28 = (<unnamed-signed:1>) _10;
_29 = 0 - _27;
_30 = _29 - _28;
_31 = (unsigned long) _30;
MEM <unsigned long> [(unsigned _BitInt(400) *)&<retval> + 32B] = _31;
Now, the last thing is what is wrong. We need to do two subtractions
(or after folding one negation and one subtraction), and while in the
original operation signed overflow is indeed undefined, it just means
that the two operations together don't overflow, but one of them can.
In this testcase (in foo function) on aarch64, _26 is 1 (the most
significant bit of 257-bit negative value) and _10 is also 1 (borrow
from within the loop). When we perform this computation in signed 1-bit
precision, we have 0 - -1 (overflow) and -1 - -1 (another overflow).
The RTL emitted for this then results in miscompilation, but we really
shouldn't introduce UB into the IL for something that didn't have UB
originally.
So, the following patch forces use of unsigned type for these and casts
to the signed one only at the end.
2026-07-31 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/126503
* gimple-lower-bitint.cc (bitint_large_huge::handle_plus_minus): If
IFN_ADDC/IFN_SUBC can't be used and rhs1_type is not the limb type
and is signed, perform both additions or both subtractions in
unsigned type for the rhs1_type and cast to rhs1_type at the end.
Jakub Jelinek [Fri, 31 Jul 2026 07:05:50 +0000 (09:05 +0200)]
gimplify: Allow declarations in recalculate_side_effects [PR126497]
The following testcase ICEs, because we decide to fold a comparison
into just one of its operands, we call recalculate_side_effects on that
and ICE on the assertion that it isn't called on anything unexpected
(here PARM_DECL).
Already some time ago we had to add an exception for SSA_NAME for the
same reason.
The tcc_declaration case is slightly different, TREE_SIDE_EFFECTS is
sometimes present on those if they are TREE_THIS_VOLATILE, but it is
something the FE should take care of when creating those decls, not
a business of the gimplifier.
2026-07-31 Jakub Jelinek <jakub@redhat.com>
PR middle-end/126497
* gimplify.cc (recalculate_side_effects): Return for
tcc_declaration.
* gcc.dg/bitint-141.c: New test.
Reviewed-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Jakub Jelinek [Fri, 31 Jul 2026 07:03:05 +0000 (09:03 +0200)]
match.pd: Fix (a & b) == (a ^ b) -> !(a | b) simplification [PR126490]
The following testcase is miscompiled.
We have 2 different simplifications
(a & b) ^ (a == b) -> !(a | b)
(a & b) == (a ^ b) -> !(a | b)
where both a and b are truth_valued_p. That doesn't mean they have
boolean type, it means that either they have integral type with one bit
precision (boolean, unsigned or signed) or they are result of comparisons
etc.
Now, because both a and b appear as operands of the same &, they necessarily
have the same or uselessly compatible type. For the first case, the a == b
comparison necessarily has to have the same type too and so type is the same
type as well.
For the second case that is not the case, e.g. in the problematic
testcase both a and b are unsigned _BitInt(1) while == has int type, but
it could very well be also that a and b are results of comparisons etc.
and have int type.
Now, the comment properly uses ! for the replacement, but the replacement
of the simplification actually uses bit_not, so ~. ~ is fine for 1-bit
precision, but not for wider ones.
The following patch differentiates between the case when a and b have
1-bit precision type, then it ensures ~ is done in that type and only
then it is converted to type, while for other cases it does ^ 1 instead.
2026-07-31 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/126490
* match.pd ((a & b) == (a ^ b) -> !(a | b)): If @0 has
integral one bit precision type, use (convert:type ...) around the
bit_not just in case the comparison has a different result type
from the type of its operands. Otherwise do that too but with
bit_not replaced with bit_xor with one of the appropriate type.
Jakub Jelinek [Fri, 31 Jul 2026 06:58:27 +0000 (08:58 +0200)]
c++: Don't cache calls which rethrow etc. [PR126508]
The first 3 testcase below are miscompiled, we happily cache
calls during constant evaluation which don't depend just on their
arguments, but also on the current exceptions (uncaught or caught).
If we decide to cache such functions and then try to evaluate them
with different uncaught/caught exceptions (or none), we can get wrong
results.
We already don't cache calls which allocate and don't free all heap
allocations, or free some heap allocations they haven't allocated,
or which call (right now any) metafunctions, or have exited through
exception, or aren't constant.
This patch just adds the rethrow/__builtin_uncaught_exceptions/
__builtin_current_exception calls to the set of non-cacheable operations
(to be precise, e.g. rethrow would be safe to cache if we can prove
that the current exception was always thrown from within that function,
ditto __builtin_current_exception, but it is hard to figure out).
The last testcase attempts to check if we don't need something similar
also for __builtin_eh_ptr_adjust_ref, but the call to foo for some reason
isn't cached and so I don't have a proof we need to handle it too.
2026-07-31 Jakub Jelinek <jakub@redhat.com>
PR c++/126508
* constexpr.cc (cxx_eval_cxa_builtin_fn): Avoid caching
calls which rethrow or call __builtin_uncaught_exceptions
or __builtin_current_exception.
* g++.dg/cpp26/constexpr-eh20.C: New test.
* g++.dg/cpp26/constexpr-eh21.C: New test.
* g++.dg/cpp26/constexpr-eh22.C: New test.
* g++.dg/cpp26/constexpr-eh23.C: New test.
Jakub Jelinek [Fri, 31 Jul 2026 06:56:03 +0000 (08:56 +0200)]
range-op-float: Fix up inf handling in other reverse ops [PR126464]
On Thu, Jul 30, 2026 at 09:31:17AM +0200, Richard Biener wrote:
> > The following testcase is miscompiled since my r16-1108 change.
> > The problem is if we handle a reverse of a narrowing float to float cast
> > (in the example there are double -> float and long double -> double
> > cast) and the lhs range is [-inf, -inf] or [+inf, +inf] (note, regardless
> > of whether some NaNs are allowed or not, so not necessarily
> > lhs.known_isinf ()), then handling that range in the wider type also
> > as [-inf, -inf] or [+inf, +inf] is wrong, e.g. for the double -> float
> > conversion, [-inf, -0x0.ffffff8p+128] double range could map to just
> > that [-inf, -inf]. We have already float_widen_lhs_range function
> > but that just extends the range by +/-1ulp or 0.5ulp if the bounds
> > are finite. If the range isn't singleton (except for optional NaN),
> > then the minimum (or maximum) finite is already in the range, so this just
> > extends the case where they are singleton.
> > I don't know how to portably figure out that 0x0.ffffff8p+128 for
> > double -> float (especially when in float_widen_lhs_range we don't know
> > yet the wider type), so the patch just uses the +/-1ulp extension (i.e.
> > [-inf, min_finite] or [+inf, max_finite] case.
On a second thought, this actually isn't specific to just reverse of
narrowing float to float casts, it is a problem for any other reverse binary
ops too.
E.g. the following testcase is miscompiled at -O2 since r13-3926-gd4c2f1d376da
(but works with -O0). The lhs of the addition is [-inf, -inf], one of its
operand is [-1e304, -1e300] and we think the other operand has to be
[-inf, -inf]. That is obviously wrong, even much larger operands can result
in -inf, anything below -DBL_MAX + -1e300 where x + -1e300 doesn't round to
-DBL_MAX or higher but to -inf.
So, the following patch just widens lb of +inf and ub of -inf by 1ulp for
all callers (and thus doesn't need the also_inf argument.
2026-07-31 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/126464
* range-op-float.cc (float_widen_lhs_range): Remove also_inf
argument, replace its uses as if it was always true.
(operator_cast::op1_range): Don't pass third argument to
float_widen_lhs_range.
Jakub Jelinek [Fri, 31 Jul 2026 06:53:52 +0000 (08:53 +0200)]
match.pd: Fix up ((C << A) & D) != 0 simplification [PR126476]
This simplification for power of two @1 and @2 folds to false (resp.
to true for the == version) if @1 is larger than @2 (in unsigned
comparison), because @1 & @2 is known to be zero (i.e. for shift count 0)
and for shift count larger than that it will be zero too, either because
@1 << @0 is even larger, or if @0 is too large @1 << @0 overflows to zero.
This is the case of e.g. ((4 << x) & 2) != 0, which is always false.
Now, this PR is about a different problem, if @1 is smaller than @2, say
((1 << x) & 256) != 0, but x has a very narrow type, say unsigned _BitInt(3),
then the largest possible value of x is 7 and ((1 << 7) & 256) is
still 0, 1 << 7 is 128 and so still smaller than 256.
So, if c1 - c2 doesn't fit into the shift count type
(resp. for the other case c2 - c1), it will be also always false (resp.
true).
Trying to improve it and using range of x (aka @0) is not needed,
this simplification folds it into @0 != (c1 - c2) and so will be folded
later. Just the case where c1 - c2 overflows is problematic because
we've lost the details (unless we'd promote both operands or something).
Another possible way to do this would be build_int_cst and check for
the overflow flags, but I think this is shorter.
2026-07-31 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/126476
* match.pd (((C << A) & D) != 0 -> A == 0,
((C << A) & D) == 0 -> A != 0): Fold to false/true if
c1 - c2 resp. c2 - c1 doesn't fit into TREE_TYPE (@0).
Jakub Jelinek [Fri, 31 Jul 2026 06:47:54 +0000 (08:47 +0200)]
c++: Fix up check_return_expr for expansion stmts [PR126420]
The first testcase below is rejected because of a deduction failure,
the second testcase ICEs.
The first testcase is IFNDR according to
https://eel.is/c++draft/temp.res.general#6.2
- no valid specialization, ignoring static_assert-declarations that
fail, can be generated for the compound-statement of an
expansion-statement and there is no instantiation of it,
so rejecting it is fine and accepting it silently too.
But we ICE on the second testcase and that is a problem,
we set current_function_returns_value = 1 in check_return_expr
when the return value is dependent, and then don't instantiate it,
and as it is the only return from the function, when we try to expand
it we try to create dependent RESULT_DECL etc. for it and ICE.
The following patch just defers what check_return_expr normally
does in expansion statement bodies. For expansion statement not
within a template check_return_expr will be called again when
we try to instantiate the body (if at all), similarly for partial
specialization we don't try to find out if the expansion stmt
has constant number of iterations at that point and will invoke
check_return_expr again during the final instantiation.
2026-07-30 Jakub Jelinek <jakub@redhat.com>
PR c++/126420
PR c++/126423
* typeck.cc (check_return_expr): If in_expansion_stmt, goto
dependent before even setting current_function_returns_value.
* pt.cc (tsubst_stmt): Temporarily set in_expansion_stmt around
partial instantiation of expansion statement body.
* g++.dg/cpp26/expansion-stmt43.C: New test.
* g++.dg/cpp26/expansion-stmt44.C: New test.
Jakub Jelinek [Fri, 31 Jul 2026 06:37:18 +0000 (08:37 +0200)]
c++: Improve diagnostics for nullptr_t/info [PR126343]
We currently print std::nullptr_t or std::meta::info in diagnostics
when seeing a NULLPTR_TYPE or META_TYPE, when they aren't type aliases
(or when they are exactly those type aliases).
I think that isn't a bad idea, the aliases is what users usually
use for those. There are 2 problems with this though.
We print
decltype(nullptr)
and
decltype(nullptr) const volatile
exactly the same, both as std::nullptr_t, so the qualifiers are lost.
And, e.g. in case of a static assertion failure when people want to find
out why some reflections aren't equal we can print
note: the comparison reduces to '(^^std::meta::info == ^^std::meta:info)'
and the user then has no idea what is going on. Is it because one of
those is a type alias (which one), or because of cv-qual differences,
or both?
The following patch prints the aliases in normal %qT etc. printing,
if cv qualified prints qualifications after them (so e.g.
'std::nullptr_t const' or 'std::meta::info volatile').
And, when printing a reflection expression, it differentiates even
between the type alias case and non-alias, so for non-aliases prints
'decltype(nullptr)' or 'decltype(^^int) const volatile' etc.
2026-07-31 Jakub Jelinek <jakub@redhat.com>
PR c++/126343
* error.cc (dump_type) <case NULLPTR_TYPE>: Call
pp_c_type_qualifier_list.
(dump_type) <case META_TYPE>: Likewise.
(dump_expr) <case REFLECT_EXPR>: For REFLECT_EXPR on
non-typedef META_TYPE or NULLPTR_TYPE print
decltype(^^int) or decltype(nullptr).
Patrick Palka [Fri, 31 Jul 2026 01:18:38 +0000 (21:18 -0400)]
c++: resolvedness of resolve_nondeduced_context result [PR126406]
In r16-5967-gbae0ed69e1862a we removed the mark_used call from
resolve_nondeduced_context under the rationale that it should be
the caller's responsiblity to mark_used.
Removing the call however now means that resolve_nondeduced_context
could return a specialization whose type is not yet fully resolved
(i.e. has an uninstantiated noexcept or undeduced return type), and
callers that immediately inspect TREE_TYPE of the result (such as
standard_conversion and build_conditional_expr) now misbehave.
In light of such callers, this patch reverts r16-5967; it's not
necessary to fix PR119343 because after r16-6276 convert_to_void
now properly propagates an error_mark_node result from
resolve_nondeduced_context.
James K. Lowden [Thu, 30 Jul 2026 22:41:05 +0000 (18:41 -0400)]
cobol: New warning to allow REDEFINES anywhere in data item definition.
The new warning -Wredefines-first (an error by default) allows the
user to reduce the error to a warning, or suppress it. Suppression is
automatic with -dialect mf.
This is a wrong-code problem starting with the recent check_initializer
simplification (r17-1661). I thought the fix would be to bring some of
those dropped conditions back, but now I think the change just uncovered
a latent bug.
Since r17-1661, when initializing 'm' of type 'M[2]' we no longer call
build_aggr_init_full_exprs in check_initializer; instead, we go on to
store_init_value -> split_nonconstant_init. There we arrive with:
which so far seems OK. The type is an array so split_nonconstant_init_1
delegates to build_vec_init and returns true which, as the comment says,
should mean that "the whole of the value was initialized by the generated
statements". This is inaccurate: since try_const and do_static_init are
both true in build_vec_init, we have split out the constant initializer
(the {.a={.p=&empty.str}, .b={.p=&empty.str}} part) into DECL_INITIAL:
so we have both dynamic and static initializers. But since
split_nonconstant_init_1 returns bool, it's not ready to signal this case
to split_nonconstant_init, which then does:
and then overwrites DECL_INITIAL (dest). So we've lost a half of the
initializer and got wrong-code as the result.
This patch fixes it by not throwing away the DECL_INITIAL that
build_vec_init set for us. I suppose another approach would be
to somehow change split_nonconstant_init_1/ARRAY_TYPE to follow
the element pruning/add_stmt like the rest of the function, but that
seems more complicated.
PR c++/126335
gcc/cp/ChangeLog:
* typeck2.cc (split_nonconstant_init): Assert that DECL_INITIAL
is initially null. Don't clear DECL_INITIAL if build_vec_init
set it. Only clear TREE_READONLY if CODE has side-effects.
AArch64: Relax regexps in tests to let them pass with -fweb
The -fweb option changes the way that GCC allocates
registers. -fweb is not enabled by default, so we
have never previously noticed that some AArch64 tests
have unreasonably strict expectations about register
allocation. This patch relaxes those expectations.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/ffs.c: Relax test expectations.
* gcc.target/aarch64/frecpe_1.c: As above.
* gcc.target/aarch64/frecpe_2.c: As above.
Eric Botcazou [Thu, 30 Jul 2026 16:29:51 +0000 (18:29 +0200)]
Ada: Fix bogus error for 'Unrestricted_Access of overloaded subprogram
This plugs an old loophole in Analyze_Attribute for the handling of the
GNAT specific Unrestricted_Access attribute.
gcc/ada/
PR ada/126482
* sem_attr.adb (Analyze_Attribute): Treat Unrestricted_Access like
[Unchecked_]Access when it comes to the overloading of the prefix.
Jason Merrill [Wed, 29 Jul 2026 18:04:24 +0000 (14:04 -0400)]
c++: anonymous namespace in module partition [PR126209]
Here since r16-4484 we include all namespaces in the current purview in a
module, even if the namespace comes from another partition. That breaks for
an anonymous namespace, which is local to the TU (and added to the
definition of TU-local entity by P2996 Reflection); here _c ended up
representing the anonymous namespace from _a separately from the same one
passed along from _b, leading to an ICE trying to import them into the same
slot in _d. I tried just adding namespaces to is_tu_local_entity, but that
broke other things, so for 16.2 let's handle them here.
PR c++/126209
gcc/cp/ChangeLog:
* module.cc (depset::hash::add_namespace_entities): Don't
force out anonymous namespaces.
gcc/testsuite/ChangeLog:
* g++.dg/modules/anon-5_a.C: New test.
* g++.dg/modules/anon-5_b.C: New test.
* g++.dg/modules/anon-5_c.C: New test.
* g++.dg/modules/anon-5_d.C: New test.
[frange] Store sub-ranges in a variable-length trailing array.
frange_storage held a fixed frange_pair m_pairs[MAX_PAIRS], so every
cached range reserved space for MAX_PAIRS sub-ranges even though the
large majority hold one. Mirror irange_storage: a trailing frange_pair
array that alloc () sizes to the range's actual num_pairs ().
Tested on ppc64le Linux. The usual regstrap, LAPACK, Fortran assembly
checks for no functional changes apply.
gcc/ChangeLog:
* value-range-storage.h (class frange_storage): Replace the fixed
m_pairs[MAX_PAIRS] with a variable-length trailing array and an
m_max_ranges capacity; declare size and the constructor.
* value-range-storage.cc (frange_storage::size): New.
(frange_storage::alloc): Allocate size (r) bytes.
(frange_storage::frange_storage): New; record m_max_ranges.
(frange_storage::fits_p): Check m_max_ranges.
Replace the single-interval union_ with a sub-range aware one.
Like the intersect rewrite, do this ahead of raising MAX_PAIRS. It is
still 1, so set_pairs collapses the result back to a single range. No
functional change.
Tested on ppc64le: regstrap, LAPACK, no changes on a corpus of Fortran
files.
gcc/ChangeLog:
* value-range.cc (frange::union_): Merge both operands' sub-ranges
via set_pairs instead of widening to the hull.
Richard Biener [Thu, 30 Jul 2026 12:27:59 +0000 (14:27 +0200)]
Deal with all vector defs in vectorizable_live_operation
After no longer requiring copies for existing vector defs we
have to deal with them. vectorizable_live_operation computes
an insert location based on them, so insert on region entry
if required.
* tree-vect-loop.cc (vectorizable_live_operation): Insert
on entry when the vector def is a default def or a constant.
Eikansh Gupta [Wed, 3 Jun 2026 10:16:29 +0000 (15:46 +0530)]
MATCH: Simplify zero/sign extension bit operations [PR122848]
Fold bitwise operations involving zero and sign extensions from the same
low-precision value. The AND case folds to the zero extension, and the
OR case folds to the sign extension.
Eikansh Gupta [Wed, 17 Jun 2026 04:28:16 +0000 (09:58 +0530)]
MATCH: fold signbit comparison and conditional negate to copysign [PR109843]
Fold (signbit (x) cmp1 0) cmp (signbit (y) cmp2 0) ? y : -y
to copysign (y, +-x). The result keeps the magnitude of Y and takes its
sign from X (or -X). Emitted as IFN_COPYSIGN when the target supports it.
PR tree-optimization/109843
gcc/ChangeLog:
* match.pd ((signbit (x) cmp 0) cmp (signbit (y) cmp 0) ? y : -y):
New simplification to copysign (y, +-x).
Bohan Lei [Thu, 23 Jul 2026 01:36:30 +0000 (09:36 +0800)]
RISC-V: Add intrinsic support for Zvabd
This commit adds intrinsic support for Zvabd. The original vwabad
machine description pattern would cause an ICE when emitting the
intrinsic because operand 0 and operand 2 are different pseudos,
and operand 2 has a constraint of "0", while operand 0 is marked as
read-write "+". The vwmacc-like pattern is now used to support correct
intrinsic generation and to better reflect the semantics. Pan Li's new
overlap constraint is used according to Robin's review comments of v2.
Prior to this change, the vectorizer estimated unrealistically high
costs for some scalar code: a cost was charged for each narrowing
conversion, even though those conversions are effectively free as
part of the associated stores. Consequently, the vectorizer could
decide to vectorize code that should not have been vectorized.
Scalar costs are inevitably somewhat overestimated in the case of
byte order reversals that should cause GCC to generate a 'rev'
instruction, because the vectorizer estimates costs independently of
the store-merging pass that discovers such reversals in scalar code.
When predicated tails are enabled for basic block SLP, the scalar cost
of reversals can be overestimated by so much that they are vectorized.
That will not happen after this change is applied.
The AArch64 backend now uses a new vectorizer function,
vect_is_truncating_store, to tell whether a given stmt truncates the
input of a store. This function is analogous to an existing
function, vect_is_extending_load, which tells whether a given stmt
extends the result of a load. The two functions are called in
roughly the same places, to help with the accuracy of costing scalar
and vector stmts.
A truncating assignment that has multiple uses should not be in an
SLP tree being costed, but it seems convenient to use single_imm_use
anyway (and it fits the expected/desired case we need to identify).
gcc/ChangeLog:
* config/aarch64/aarch64.cc (aarch64_detect_scalar_stmt_subtype):
Call the new vect_is_truncating_store function and return 0 if
vect_is_truncating_store returns true.
(aarch64_sve_adjust_stmt_cost): Call vect_is_truncating_store
and assign 0 to stmt_cost if vect_is_truncating_store returns
true.
* tree-vectorizer.h (vect_is_truncating_store): New function
analogous to vect_is_extending_load.
Richard Biener [Wed, 29 Jul 2026 12:26:42 +0000 (14:26 +0200)]
Avoid SSA copies from vect_add_slp_permutation
In the past we needed a stmt_vec_info for all vector defs. Not
anymore.
* tree-vect-slp.cc (vect_add_slp_permutation): We no longer
need a copy when the extraction is readily available.
(vect_schedule_slp_node): Handle default defs or constants
in vector defs.
Fortran support for init,set,shutdown OpenACC directives
This patch adds parsing and libgomp runtime calls for these directives,
sharing the existing implementation with runtime API calls. It also
includes support for the device_type and device_num clauses in the
Fortran front-end.
For the device_type clause, the current implementation limits usage to
accepting only a single clause per directive. While the OpenACC
specification states that device_type should modify the device for
subsequent clauses inside other directives or constructs, supporting
this behavior requires a larger refactoring and may be addressed in
the future.
The set directive does not yet support the default_async clause, as
further discussion is needed to agree on its semantics and libgomp
implementation.
gcc/ChangeLog:
* builtin-types.def (BT_FN_VOID_INT_INT): New definition.
* omp-builtins.def (BUILT_IN_GOACC_INIT): New builtin for
init directive.
(BUILT_IN_GOACC_SHUTDOWN): New builtin for shutdown directive.
(BUILT_IN_GOACC_SET_DEVICE): New builtin for set directive.
gcc/fortran/ChangeLog:
* dump-parse-tree.cc (show_omp_clauses): Dump OpenACC DEVICE_TYPE
and DEVICE_NUM clauses.
(show_omp_node): Handle INIT, SHUTDOWN, and SET directives.
(show_code_node): Likewise.
* frontend-passes.cc (gfc_code_walker): Walk device_num_expr for
INIT, SHUTDOWN, and SET directives.
* gfortran.h (enum gfc_statement): Add ST_OACC_INIT,
ST_OACC_SHUTDOWN, and ST_OACC_SET.
(gfc_omp_clauses): Add device_num_expr and oacc_device_type
fields.
(enum gfc_exec_op): Add EXEC_OACC_INIT, EXEC_OACC_SHUTDOWN, and
EXEC_OACC_SET.
* match.h (gfc_match_oacc_init): Declare.
(gfc_match_oacc_shutdown): Likewise.
(gfc_match_oacc_set): Likewise.
* openmp.cc (gfc_free_omp_clauses): Free device_num_expr.
(match_oacc_device_type_kind): New helper to parse OpenACC
device_type arguments.
(match_oacc_device_type): New helper to match the OpenACC
DEVICE_TYPE clause.
(enum omp_mask2): Add OMP_CLAUSE_DEVICE_NUM.
(gfc_match_omp_clauses): Match OpenACC DEVICE_TYPE and
DEVICE_NUM clauses.
(OACC_INIT_CLAUSES): New clause mask.
(OACC_SHUTDOWN_CLAUSES): Likewise.
(OACC_SET_CLAUSES): Likewise.
(gfc_match_oacc_init): New matcher.
(gfc_match_oacc_shutdown): Likewise.
(gfc_match_oacc_set): Likewise.
(resolve_omp_clauses): Resolve DEVICE_NUM; require at least one
of DEVICE_TYPE and DEVICE_NUM on SET.
(oacc_code_to_statement): Map new exec ops to statement codes.
(gfc_resolve_oacc_directive): Resolve INIT, SET, and SHUTDOWN
directives.
* parse.cc (decode_oacc_directive): Recognize init, set, and
shutdown directives.
(next_statement): Treat INIT, SET, and SHUTDOWN as executable
statements.
(gfc_ascii_statement): Add ASCII names for new directives.
(is_oacc): Recognize new exec ops.
* resolve.cc (gfc_resolve_blocks): Resolve INIT, SET, and
SHUTDOWN directives.
* st.cc (gfc_free_statement): Free clauses for new directives.
* trans-openmp.cc (gfc_trans_omp_clauses): Assert that
DEVICE_NUM and DEVICE_TYPE do not appear on construct clauses.
(gfc_trans_oacc_executable_directive): Lower INIT, SHUTDOWN, and
SET to GOACC builtins.
(gfc_trans_oacc_directive): Dispatch new directives.
* trans.cc (trans_code): Dispatch new directives.
* types.def (BT_FN_VOID_INT_INT): New definition.
libgomp/ChangeLog:
* libgomp.map (GOACC_2.5): Export GOACC_init, GOACC_shutdown, and
GOACC_set_device.
* libgomp_g.h (GOACC_init): Declare.
(GOACC_shutdown): Likewise.
(GOACC_set_device): Likewise.
* oacc-init.c (GOACC_DIRECTIVE_DEVICE_MASK): New macro for
supported device types.
(acc_init_1): Accept explicit device number argument.
(acc_shutdown_1): Shut down a single device or all devices of a
type.
(goacc_attach_host_thread_to_device): Whitespace fix.
(GOACC_init): New entry point for init directive.
(GOACC_shutdown): New entry point for shutdown directive.
(GOACC_set_device): New entry point for set directive.
(acc_init): Pass default device number to acc_init_1.
(acc_shutdown): Pass default device number to acc_shutdown_1.
(acc_set_device_num): Whitespace fix.
(goacc_restore_bind): Whitespace fix.
(goacc_lazy_initialize): Pass default device number to acc_init_1.
* testsuite/libgomp.oacc-fortran/init-1.f90: New test.
* testsuite/libgomp.oacc-fortran/lib-1-directives.f90: New test.
* testsuite/libgomp.oacc-fortran/lib-4-directives.f90: New test.
* testsuite/libgomp.oacc-fortran/lib-5-directives.f90: New test.
* testsuite/libgomp.oacc-fortran/lib-5-init.f90: New test.
* testsuite/libgomp.oacc-fortran/set-1.f90: New test.
* testsuite/libgomp.oacc-fortran/shutdown-1.f90: New test.
gcc/testsuite/ChangeLog:
* gfortran.dg/goacc/acc-init-1.f90: New test.
* gfortran.dg/goacc/acc-init-clauses-1.f90: New test.
* gfortran.dg/goacc/acc-set-1.f90: New test.
* gfortran.dg/goacc/acc-set-clauses-1.f90: New test.
* gfortran.dg/goacc/acc-shutdown-1.f90: New test.
* gfortran.dg/goacc/acc-shutdown-clauses-1.f90: New test.
* gfortran.dg/goacc/uninit-if-clause.f95: Test INIT with
uninitialized IF clause.
* gfortran.dg/goacc/update-if_present-2.f90: Update expected
errors now that INIT and SHUTDOWN are recognized.
Signed-off-by: Sebastian Galindo <sebastian.galindo143@gmail.com> Co-authored-by: Thomas Schwinge <tschwinge@baylibre.com>
Jakub Jelinek [Thu, 30 Jul 2026 07:56:41 +0000 (09:56 +0200)]
range-op-float: Fix up inf handling in reverse narrowing float to float cast [PR126464]
The following testcase is miscompiled since my r16-1108 change.
The problem is if we handle a reverse of a narrowing float to float cast
(in the example there are double -> float and long double -> double
cast) and the lhs range is [-inf, -inf] or [+inf, +inf] (note, regardless
of whether some NaNs are allowed or not, so not necessarily
lhs.known_isinf ()), then handling that range in the wider type also
as [-inf, -inf] or [+inf, +inf] is wrong, e.g. for the double -> float
conversion, [-inf, -0x0.ffffff8p+128] double range could map to just
that [-inf, -inf]. We have already float_widen_lhs_range function
but that just extends the range by +/-1ulp or 0.5ulp if the bounds
are finite. If the range isn't singleton (except for optional NaN),
then the minimum (or maximum) finite is already in the range, so this just
extends the case where they are singleton.
I don't know how to portably figure out that 0x0.ffffff8p+128 for
double -> float (especially when in float_widen_lhs_range we don't know
yet the wider type), so the patch just uses the +/-1ulp extension (i.e.
[-inf, min_finite] or [+inf, max_finite] case.
2026-07-30 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/126464
* range-op-float.cc (float_widen_lhs_range): Add also_inf argument
defaulted to false, if true, extend even lb of +inf and ub of -inf.
(operator_cast::op1_range): Adjust float_widen_lhs_range caller.
Jakub Jelinek [Thu, 30 Jul 2026 07:54:53 +0000 (09:54 +0200)]
asan: Don't emit __asan_handle_no_return_call before __asan_report_* calls [PR126084]
Alex reported that since my r17-2388 fix we now emit an undesirable
__asan_handle_no_return call before the __asan_report_{load,store}*
calls added during bitintlower pass. Normally (when large/huge _BitInt
is not involved), those are added by the sanopt pass which runs after
the asan pass and so aren't instrumented.
The following patch avoids instrumenting those.
Unfortunately the first hunk isn't all that is needed.
That is because for the bitintlower added __asan_report_* calls
gimple_call_builtin_p (stmt, BUILT_IN_NORMAL) returns false
due to argument type mismatch.
THe C/C++/Fortran FEs use
DEF_PRIMITIVE_TYPE (BT_PTRMODE, (*lang_hooks.types.type_for_mode)(ptr_mode, 0))
and so use signed type with TYPE_MODE (ptr_mode).
The fallback initialization in initialize_sanitizer_builtins
(done for non-C/C++/Fortran FEs) uses for PTRMODE instead
pointer_sized_int_node type, which is initialized to:
pointer_sized_int_node = build_nonstandard_integer_type (POINTER_SIZE, 1);
where
ptr_mode = as_a <scalar_int_mode>
(mode_for_size (POINTER_SIZE, GET_MODE_CLASS (Pmode), 0).require ());
so, I think both have the same precision, just one is signed and one
unsigned. And then asan_expand_poison_ifn uses pointer_sized_int_node.
The following patch just changes initialize_sanitizer_builtins and
asan_expand_poison_ifn to do the same thing as the C/C++/Fortran FEs here.
Seems asan.cc is full of similar builtin argument type mismatches, but
I've changed only what was needed for this patch.
2026-07-30 Jakub Jelinek <jakub@redhat.com>
PR middle-end/126084
* asan.cc (maybe_instrument_call): Don't instrument
BUILT_IN_ASAN_REPORT_{LOAD,STORE}{1,2,4,8,16,_N} builtins.
(initialize_sanitizer_builtins): Use
(*lang_hooks.types.type_for_mode) (ptr_mode, 0) instead of
pointer_sized_int_mode for PTRMODE arguments.
(asan_expand_poison_ifn): Likewise.
Jakub Jelinek [Thu, 30 Jul 2026 07:53:50 +0000 (09:53 +0200)]
match.pd: Optimize .PARITY (.BITREVERSE (x))
When working on the last patch, I've noticed that the parity(bswap(x))
optimization only optimizes the 16/32/64/128-bit bswaps, but not
generic _BitInt bswap, and doesn't optimize any of the bitreverses.
Both all bswap and all bitreverse builtins/ifns preserve values of all the
bits, just permute them, so parity (and popcount too) can be optimized.
2026-07-30 Jakub Jelinek <jakub@redhat.com>
* match.pd (parity(bswap(x)) is parity(x)): Use BSWAP BITREVERSE
instead of BUILT_IN_BSWAP16 BUILT_IN_BSWAP32 BUILT_IN_BSWAP64
BUILT_IN_BSWAP128.
The parity(~X) simpliciation to parity(X) is incorrect for types with
odd element precision, in that case parity(~X) is equivalent to
parity(X) ^ 1.
The following patch fixes this.
2026-07-30 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/126471
* match.pd (parity(~X) is parity(X)): Only optimize this way
if element_precision is even, otherwise optimize into parity(X) ^ 1.
* gcc.dg/bitint-139.c: New test.
Reviewed-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Jin Ma [Tue, 28 Jul 2026 11:58:16 +0000 (19:58 +0800)]
RISC-V: Fix sibcall address legalization in MI thunks [PR126449]
MI thunks generate RTL as if reload were complete and emit it directly
without running register allocation. Creating a pseudo while
materializing an invalid sibcall address therefore triggers the
gen_reg_rtx assertion.
Use STATIC_CHAIN_REGNUM for this post-reload thunk path. It is available
as a temporary in MI thunks and belongs to SIBCALL_REGS. Keep using a
pseudo for sibcalls expanded before register allocation.
PR target/126449
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_legitimize_call_address): Use
STATIC_CHAIN_REGNUM when a sibcall address is materialized in
post-reload thunk code.
gcc/testsuite/ChangeLog:
* g++.target/riscv/pr126449.C: New test.
Reported-by: Michal Jireš <mjires@suse.cz> Signed-off-by: Jin Ma <jinma@linux.alibaba.com>
Darwin maintains a separate array of register_names where the Dense Math
Registers were not added. This caused an ICE when building the darwin
cross compiler as reported in PR126438. This patch adds dense math
registers to the REGISTER_NAMES array to fix this issue.
[frange] Add set_pairs to install a set of sub-ranges.
Implement frange::set_pairs(), a function that takes an array of
sub-ranges, sorts them, fuses those that overlap, while capping the
result to MAX_PAIRS, and then installs these as the frange's
sub-ranges.
Preliminary stats show that 2 subranges cover 99.6% of all ranges
needed, so we don't bend over backwards to this super efficiently like
we do for irange. We're unlikely to ever need more than 2 subranges.
MAX_PAIRS is still 1, so set_pairs only ever installs a single
interval for now.
No changes to functionality until we flip the switch.
Tested on ppc64le: regstrap, LAPACK, no assembly accross a corpus of
Fortran files, etc.
gcc/ChangeLog:
* value-range.h (class frange): Declare set_pairs. Document the
sub-range representation and that the no-argument bounds are the
convex hull.
* value-range.cc (frange_fusible_p): New.
(frange::set_pairs): New.
(frange::flush_denormals_to_zero): Reinstall the endpoints through
set_pairs.
(frange::normalize_kind): Note a range with a gap is never varying.
(frange::verify_range): Check the sub-range invariants.
Some embedded targets set argc to zero when calling main, but then
pr126194 testcase fails because it uses argc > 0 to enable the code
that allows the test to pass. Derive the argc passed to the primary
LTOed entry point from argc >= 0, so that it isn't a link-time
constant, but the guarding condition always passes at runtime.
Andrea Pinski [Wed, 29 Jul 2026 23:44:17 +0000 (16:44 -0700)]
match: Fix some incorrect vector fp comparison combines [PR 126455]
This fixes r16-2134-gf33cc3af8fd9c4 which extended some patterns to
support vector types but these patterns are only valid for integral
types and the check that was used was VECTOR_TYPE.
This fixes it by using VECTOR_INTEGRAL_TYPE || VECTOR_BOOLCEAN_TYPE
which prevent the, for vector floating point types.
Pushed as obvious after bootstrap/test on x86_64-linux-gnu.
PR tree-optimization/126455
gcc/ChangeLog:
* match.pd: Fix up patterns dealing with bitwise AND/OR/XOR
and comparisons for floating point types.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Andrea Pinski [Wed, 29 Jul 2026 23:12:42 +0000 (16:12 -0700)]
match: Fix up expr_no_side_effects_p call for `(a != 0) ? (a / b) : 0` pattern [PR126470]
r15-3870-g6c5543d3d9c4bb introduced a fix for this pattern
to use expr_no_side_effects_p but I was testing the wrong
operand here which allowed b to become unconditional even
if that expression traps.
Puhsed as obvious after bootstrap/test on x86_64-linux-gnu.
PR tree-optimization/126470
gcc/ChangeLog:
* match.pd (`(a != 0) ? (a / b) : 0`): Fix argument
to expr_no_side_effects_p.
gcc/testsuite/ChangeLog:
* gcc.dg/torture/pr126470-1.c: New test.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
The order of the arguments for minmax_from_comparison is wrong for this
pattern. I swapped the 2 CST which in some cases could cause
incorrect code.
Pushed as obvious after a bootstrap/testing on x86_64-linux-gnu.
Note for backporting, minmax-29.c and minmax-30.c will need to be
changed slightly because we don't factor out the min/max before GCC 17.
PR tree-optimization/126456
gcc/ChangeLog:
* match.pd (`a CMP b ? MIN/MAX<a, c> : MIN/MAX<a, d>`): Fix
order of minmax_from_comparison arguments.
gcc/testsuite/ChangeLog:
* gcc.dg/torture/minmax-1.c: New test.
* gcc.dg/tree-ssa/minmax-29.c: New test.
* gcc.dg/tree-ssa/minmax-30.c: New test.
* gcc.dg/tree-ssa/minmax-31.c: New test.
* gcc.dg/tree-ssa/minmax-32.c: New test.
Signed-off-by: Andrea Pinski <andrew.pinski@oss.qualcomm.com>
Pan Li [Mon, 27 Jul 2026 07:49:10 +0000 (15:49 +0800)]
RISC-V: Add test cases for vwsubu.wv reg overlap
Add test cases for register group overlap, please
note it is not overlap as much as possible.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u16-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u16-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u16-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u16-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u16-mf4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u32-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u32-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u32-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u32-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u8-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u8-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u8-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u8-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u8-mf4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsubu_wv-u8-mf8.c: New test.
Pan Li [Mon, 27 Jul 2026 07:48:52 +0000 (15:48 +0800)]
RISC-V: Add test cases for vwsub.wv reg overlap
Add test cases for register group overlap, please
note it is not overlap as much as possible.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i16-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i16-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i16-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i16-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i16-mf4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i32-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i32-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i32-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i32-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i8-m1.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i8-m2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i8-m4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i8-mf2.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i8-mf4.c: New test.
* gcc.target/riscv/rvv/autovec/group_overlap/vwsub_wv-i8-mf8.c: New test.
Jakub Jelinek [Wed, 29 Jul 2026 21:34:54 +0000 (23:34 +0200)]
isel: Fix ICE on out of bounds vector elt access [PR126446]
The isel pass has a check for out of bounds constant index before
optimizing into .VEC_SET, but it does it using
// if index is a constant, then check the bounds
poly_uint64 idx_poly;
if (poly_int_tree_p (idx, &idx_poly))
{
poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (view_op0));
if (known_gt (idx_poly, nelts))
return false;
}
In the testcase below, idx is INTEGER_CST with long long type and
negative value, that doesn't fit into poly_uint64, so we happily convert
it into .VEC_SET.
Furthermore, the known_gt check looks wrong, already idx_poly known_eq
to nelts is too large and out of bounds for .VEC_SET.
This patch fixes that by punting if !poly_int_tree_p (idx, &idx_poly)
and poly_int_tree_p (idx), so when it is INTEGER_CST or POLY_INT_CST
which doesn't fit into poly_uint64 (so likely negative), and
uses known_ge instead of known_gt.
2026-07-29 Jakub Jelinek <jakub@redhat.com>
PR target/126446
* gimple-isel.cc (gimple_expand_vec_set_extract_expr): Punt if
idx doesn't fit into poly_uint64 but is poly_int_tree_p. Use
known_ge rather than known_gt for out of bounds check. Formatting
fixes.
James K. Lowden [Wed, 29 Jul 2026 18:00:41 +0000 (14:00 -0400)]
cobol: Accept newline in refmod pattern.
Modify lexer recognition of refmods and correct errors in is_refmod() function.
gcc/cobol/ChangeLog:
* parse.y: Report LPAREN token as '(', not ')'.
* scan.l: Remove newline exclusion from LPAREN pattern.
* scan_ante.h (rsearch): Helper function to ensure c++11 compatibility.
(trim_location): Use rsearch function.
(is_quote): New inline function to test quotiness.
(skip_string): New function to find end of string literal.
(is_refmod): Stay in bounds.
* util.cc (gcc_location_set): Decrease debug message verbosity.
Roger Sayle [Wed, 29 Jul 2026 16:39:42 +0000 (17:39 +0100)]
cris: PR rtl-optimization/126276: Restore build on cris-elf.
This patch resolves PR rtl-optimization/126276 which is a target-specific
regression on CRIS, triggered by a recent RTL simplification improvement.
The underlying problem is that cris.md's *cbranch<mode>4_btstrq1_<CC>
accepts more machines modes than the define_insn it is lowering to.
Fixed by adding the necessary modes to the *btst<mode> define_insn.
2026-07-29 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
PR target/126276
* config/cris/cris.md (*btst<BWD><ZnNNZSET): Handle BWD modes,
not just SImode.
(*cbranch<mode>4_btstrq1_<CC>): Likewise.
(*cbranch<mode>4_btstqb0_<CC>): Likewise.
Jonathan Wakely [Wed, 29 Jul 2026 15:55:39 +0000 (16:55 +0100)]
libstdc++: Fix grep for linker warning about --gc-sections [PR126452]
Current versions of GNU ld print "warning" with a lowercase 'w' so
adjust the grep patter. Also use LC_ALL=C to ensure the warning isn't
translated.
Because m4 uses square brackets as quotes, we need to use double
brackets in the grep pattern to expand to "[Ww]" in the configure
script.
libstdc++-v3/ChangeLog:
PR libstdc++/126452
* acinclude.m4 (GLIBCXX_CHECK_LINKER_FEATURES): Use LC_ALL_C and
match both "Warning" and "warning" in ld output.
* configure: Regenerate.
avoid-store-forwarding: Unshare load dest when re-applying extension [PR126434]
When store forwarding is avoided without eliminating the load (the store
only partially covers it), the extension wrapping the load's MEM is
re-applied after the bit-insert sequence, reusing SET_DEST (load) as the
move destination. As the load insn is kept here, that rtx is now shared
between two insns. That is fine for a plain REG, but in the case that the
dest is a SUBREG, it must not be shared (verify_rtx_sharing ICEs).
Unshare the destination with copy_rtx when building the move.
Bootstrapped/regtested on AArch64, x86-64 and PowerPC.
PR rtl-optimization/126434
gcc/ChangeLog:
* avoid-store-forwarding.cc (process_store_forwarding): Unshare the
load destination when building the re-extension move.
1. I forgot to negate the else value
2. one of the patterns was missing the mask.
This fixes it. The patterns moving the COND inwards are still useful because
they allow FMA forwarding as most micro-architectures don't forward FMA when
there's a random instruction like fneg in between.
Sorry for the mistakes. I added more tests to cover these now.
PR tree-optimization/126465
* gcc.target/aarch64/sve/cond_fma.c: New test.
* gcc.target/aarch64/sve/cond_fma_neg_addend.c: New test.
* gcc.target/aarch64/sve/cond_fms.c: New test.
* gcc.target/aarch64/sve/cond_fnma.c: New test.
* gcc.target/aarch64/sve/cond_fnms.c: New test.
Philipp Tomsich [Tue, 28 Jul 2026 13:28:33 +0000 (15:28 +0200)]
tree-optimization/126415 - perform inverse converted +- lookup in VN
The match.pd rewrite (T)a +- X -> (T)(a +- X') from r17-2078-g8395fa7c79eecf creates the narrow operation, assuming the
absence of overflow for an operation the program does not execute;
this results in wrong code (PR126415). Revert it and implement the
equivalence in visit_nary_op instead.
visit_nary_op value-numbers (T)(a +- b) <- (T)a +- (T)b. Add the
inverse, (T)a +- X <- (T)(a +- X'), looking up the narrow a +- X'
and converting the result. This makes the equivalence independent
of the order the two forms appear in the IL.
The transform is valid for sign changes and for widening conversions
from a type with undefined overflow when the narrow operation
dominates the statement being visited. The narrow operation is only
looked up, never created. X may be an integer constant that narrows
and extends back unchanged, or a conversion from the same narrow
type.
The sign-change case makes the fold apply to ilp32 targets as well;
remove the ilp32 xfail from the pr124545.c scan (PR116845).
Bootstrapped and regression-tested on x86_64-pc-linux-gnu.
* match.pd ((T)A +- CST -> (T)(A +- CST')): Revert.
* tree-ssa-sccvn.cc (ssa_integral_conversion_op): New function.
(vn_nary_result_avail_or_insertable_p): New function, split out
from ...
(visit_nary_op): ... here. Handle ((T)p) +- X by looking up
(p +- X') and converting the result, for X an integer constant
that narrows and extends back unchanged or a conversion from
the same narrow type.
gcc/testsuite/ChangeLog:
* gcc.dg/torture/pr126415.c: New testcase.
* gcc.dg/tree-ssa/ssa-fre-113.c: New testcase.
* gcc.dg/tree-ssa/ssa-fre-114.c: New testcase.
* gcc.dg/pr124545.c: Remove the ilp32 xfail.
Tomasz Kamiński [Tue, 28 Jul 2026 14:43:49 +0000 (16:43 +0200)]
libstdc++: Resolve UNTIL save adjustment at tzdb loading time [PR116110]
This patch moves the save calculation (ZoneInfo::calc_save) to database
loading code (reload_tzdb) instead of applying it on demand when zone
is queried (time_zone::_M_get_sys_info). This eliminates the performance
impact on non-first calls (that return the cached result), caused by
iterator adjustment checks.
Local performance test indicate a 10% cost (30ns to 33ns on average) for
cached queries with on-demand implementation (after r17-2466-g020e02fcf28),
combined with huge swings on time on first calls. This patch leads 200ms
increase (1.95s to 2.15s) on time of reload_tzdb, that happens only during
initial load (and later explicit reload).
As we need two bits of state (expanded or until_pending), I have decided
to keep the four value m_state enum.
PR libstdc++/116110
libstdc++-v3/ChangeLog:
* src/c++20/tzdb.cc (time_zone::_M_get_sys_info): Remove
ZoneInfo::calc_save invocation and related iterator adjustment.
(chrono::reload_tzdb): Calculate save (invoke calc_save) for
all infos on all zones.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
The following adds an early out for unsupported reduction operations
to avoid ICEing when the assumption that the GIMPLE stmt operand
number matches the SLP operand number breaks, as is for .CLZ with
two operands.
PR tree-optimization/126457
* tree-vect-loop.cc (vectorizable_reduction): Reject
operations where not all operands correspond to a SLP
child early.
Piotr Kubaj [Wed, 22 Jul 2026 13:45:04 +0000 (15:45 +0200)]
libgcc: rs6000: fix TOC restore when unwinding on FreeBSD powerpc64 ELFv2 [PR target/125803]
On powerpc64, when the unwind info for a frame does not explicitly
describe how r2 (the TOC pointer) was saved -- which is the normal case
for the linker-generated PLT call stubs -- frob_update_context inspects
the code stream to locate the saved TOC and arranges for r2 to be
restored from it.
The FreeBSD version of this hook hard-coded the ELFv1 TOC save slot
offset of 40 bytes, matching "std r2,40(r1)" (0xF8410028) and
"ld r2,40(r1)" (0xE8410028). FreeBSD/powerpc64 (both big-endian and
powerpc64le) uses ELFv2, where the TOC is saved at offset 24
("std r2,24(r1)" / "ld r2,24(r1)"). As a result the checks never
matched, r2 was left unrestored, and code reached by unwinding -- e.g. a
C++ catch handler in a different module than libgcc_s -- ran with the
wrong TOC. Any global or PLT access from such a handler then computed a
bogus address, typically crashing. This made C++ exceptions unusable on
FreeBSD/powerpc64le whenever gcc's shared libgcc_s provided the unwinder
(for instance any clang-built C++ program that pulls in libgfortran).
Define TOC_SAVE_SLOT based on _CALL_ELF (24 for ELFv2, 40 otherwise) and
use it throughout, and guard the ELFv1-only code-reading cases (the old
PLT stub form and the function pointer call sequence) with
_CALL_ELF != 2, mirroring linux-unwind.h.
libgcc/ChangeLog:
PR target/125803
* config/rs6000/freebsd-unwind.h (TOC_SAVE_SLOT): New macro,
defined according to _CALL_ELF.
(frob_update_context): Use TOC_SAVE_SLOT instead of the
hard-coded ELFv1 offset 40 when checking for and locating the
saved TOC, so that r2 is restored correctly under ELFv2. Guard
the ELFv1-only PLT stub and function pointer call sequences
with _CALL_ELF != 2, mirroring linux-unwind.h.
Thomas Schwinge [Mon, 27 Jul 2026 16:23:49 +0000 (18:23 +0200)]
OpenMP: Constructors and destructors for "declare target" static aggregates: Simplify offload tree dump scanning in test cases
The tests added in commit f1bfba3a9b3f31e3e06bfd1911c9f223869ea03f
'OpenMP: Constructors and destructors for "declare target" static aggregates'
carefully distinguish between AMD and NVIDIA GPU offloading compilations'
offload tree dump scanning -- but do exactly the same for both. (As expected.)
Therefore, no reason to duplicate these directives.
LoongArch: Adjust testcase for lasx-vec-construct-opt.c
Follow up to r17-2354-g10f6223d833, which changed the behavior of
vec_duplicate. The LoongArch architecture testcase need adjustments to
accommodate this change.
Jakub Jelinek [Wed, 29 Jul 2026 08:15:11 +0000 (10:15 +0200)]
i386: Fix ICE on out of bounds vector elt access [PR126446]
The following testcase ICEs on x86_64.
The isel pass has a check for out of bounds constant index before
optimizing into .VEC_SET, but it does it using
// if index is a constant, then check the bounds
poly_uint64 idx_poly;
if (poly_int_tree_p (idx, &idx_poly))
{
poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (view_op0));
if (known_gt (idx_poly, nelts))
return false;
}
In the testcase below, idx is INTEGER_CST with long long type and
negative value, that doesn't fit into poly_uint64, so we happily convert
it into .VEC_SET.
And another problem is that the x86 backend isn't trying to be careful
and handle out of bounds elt gracefully (I think it could still in theory
happen, if GIMPLE lets it through but e.g. something during expansion
figures out the index is constant or whatever).
The following patch fixes it in the backend to avoid triggering UB at compile
time by doing HOST_WIDE_INT_1U << elt etc. when elt is negative or too
large. In order to avoid ICE, we need to emit something, so I emit
a no-op move, out of bounds vector set shouldn't change anything in
the target.
gimple-isel.cc will be changed incrementally.
2026-07-29 Jakub Jelinek <jakub@redhat.com>
PR target/126446
* config/i386/i386-expand.cc (ix86_expand_vector_set): If elt is
out of bounds, emit a no-op move.