Age | Commit message (Collapse) | Author | Files | Lines |
|
Because coroutines insert a call to the resumer between the initialization
of the return value and the actual return to the caller, we need to
duplicate the work of gimplify_return_expr for the !aggregate_value_p case.
PR c++/117364
PR c++/118874
gcc/cp/ChangeLog:
* coroutines.cc (cp_coroutine_transform::build_ramp_function): For
!aggregate_value_p return force return value into a local temp.
gcc/testsuite/ChangeLog:
* g++.dg/coroutines/torture/pr118874.C: New test.
Co-authored-by: Jakub Jelinek <jakub@redhat.com>
|
|
vld1q_s8_x3, vld1q_s16_x3, vld1q_s8_x4 and vld1q_s16_x4 were expecting
pointers to unsigned integers. These parameters should be pointers to
signed integers.
gcc/ChangeLog:
PR target/118942
* config/arm/arm_neon.h (vld1q_s8_x3): Use int8_t instead of
uint16_t.
(vld1q_s16_x3): Use int16_t instead of uint16_t.
(vld1q_s8_x4): Likewise.
(vld1q_s16_x4): Likewise.
gcc/testsuite/ChangeLog:
PR target/118942
* gcc.target/arm/simd/vld1q_base_xN_1.c: Add -Wpointer-sign.
Signed-off-by: Hannes Braun <hannes@hannesbraun.net>
|
|
- Use __builtin_unreachable to suppress a false-positive "control
reaches end of non-void function" warning in the recursive lambda
(which the existing tests failed to notice since test01 wasn't
being called at runtime)
- Relax the constraints on views::concat in the single-argument case
as per PR115215
- Add an input_range requirement to that same case as per LWG 4082
- In the const-converting constructor of concat_view's iterator,
don't require the first iterator to be default constructible
PR libstdc++/115215
PR libstdc++/115218
libstdc++-v3/ChangeLog:
* include/std/ranges
(concat_view::iterator::_S_invoke_with_runtime_index): Use
__builtin_unreachable in recursive lambda to certify it always
exits via 'return'.
(concat_view::iterator::iterator): In the const-converting
constructor, direct initialize _M_it.
(views::_Concat::operator()): Adjust constraints in the
single-argument case as per LWG 4082.
* testsuite/std/ranges/concat/1.cc (test01): Call it at runtime
too.
(test04): New test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
|
|
Add check for constrained auto type specifier in function declaration or
function type declaration with trailing return type. Issue error if such
usage is detected.
Test file renamed, and added a new test for type declaration.
Successfully bootstrapped and regretested on x86_64-pc-linux-gnu:
Added 6 passed and 4 unsupported tests.
PR c++/100589
gcc/cp/ChangeLog:
* decl.cc (grokdeclarator): Issue an error for a declarator with
constrained auto type specifier and trailing return types. Include
function names if available.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/concepts-pr100589.C: New test.
Signed-off-by: Da Xie <xxie_xd@163.com>
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
expansion
The PARALLEL created in aarch64_evpc_dup is used to hold the lane number.
It is not appropriate for it to have a vector mode.
Other such uses use VOIDmode.
Do this here as well.
This avoids the risk of generic code treating the PARALLEL as trapping when it
has floating-point mode.
Bootstrapped and tested on aarch64-none-linux-gnu.
Signed-off-by: Kyrylo Tkachov <ktkachov@nvidia.com>
PR rtl-optimization/119046
* config/aarch64/aarch64.cc (aarch64_evpc_dup): Use VOIDmode for
PARALLEL.
|
|
mode as trapping
In this testcase late-combine was failing to merge:
dup v31.4s, v31.s[3]
fmla v30.4s, v31.4s, v29.4s
into the lane-wise fmla form.
This is because late-combine checks may_trap_p under the hood on the dup insn.
This ended up returning true for the insn:
(set (reg:V4SF 152 [ _32 ])
(vec_duplicate:V4SF (vec_select:SF (reg:V4SF 111 [ rhs_panel.8_31 ])
(parallel:V4SF [
(const_int 3 [0x3])]))))
Although mem_trap_p correctly reasoned that vec_duplicate and vec_select of
floating-point modes can't trap, it assumed that the V4SF parallel can trap.
The correct behaviour is to recurse into vector inside the PARALLEL and check
the sub-expression. This patch adjusts may_trap_p_1 to do just that.
With this check the above insn is not deemed to be trapping and is propagated
into the FMLA giving:
fmla vD.4s, vA.4s, vB.s[3]
Bootstrapped and tested on aarch64-none-linux-gnu.
Apparently this also fixes a regression in
gcc.target/aarch64/vmul_element_cost.c that I observed.
Signed-off-by: Kyrylo Tkachov <ktkachov@nvidia.com>
gcc/
PR rtl-optimization/119046
* rtlanal.cc (may_trap_p_1): Don't mark FP-mode PARALLELs as trapping.
gcc/testsuite/
PR rtl-optimization/119046
* gcc.target/aarch64/pr119046.c: New test.
|
|
The following testcase is miscompiled during evrp.
Before vrp, we have (from ccp):
# RANGE [irange] long long unsigned int [0, +INF] MASK 0xffffffffffffc000 VALUE 0x2d
_3 = _2 + 18446744073708503085;
...
# RANGE [irange] long long unsigned int [0, +INF] MASK 0xffffffffffffc000 VALUE 0x59
_6 = (long long unsigned int) _5;
# RANGE [irange] int [-INF, +INF] MASK 0xffffc000 VALUE 0x34
_7 = k_11 + -1048524;
switch (_7) <default: <L5> [33.33%], case 8: <L7> [33.33%], case 24: <L6> [33.33%], case 32: <L6> [33.33%]>
...
# RANGE [irange] long long unsigned int [0, +INF] MASK 0xffffffffffffc07d VALUE 0x0
# i_20 = PHI <_3(4), 0(3), _6(2)>
and evrp is now trying to figure out range for i_20 in range_of_phi.
All the ranges and MASK/VALUE pairs above are correct for the testcase,
k_11 and _2 based on it is a result of multiplication by a constant with low
14 bits cleared and then some numbers are added to it.
There is an obvious missed optimization for which I've filed PR119039,
simplify_switch_using_ranges could see that all the labels but default
are unreachable because the controlling expression has
MASK 0xffffc000 VALUE 0x34 and none of 8, 24 and 32 satisfy that.
Anyway, during range_of_phi for i_20, we process the PHI arguments
in order. For the _3(4) case, we figure out that it is reachable
through the case 24: case 32: labels only of the switch and that
0x34 - 0x2d is 7, so derive
[irange] long long unsigned int [17, 17][25, 25] MASK 0xffffffffffffc000 VALUE 0x2d
(the MASK/VALUE just got inherited from the _3 earlier range).
Now (not suprisingly because those labels aren't actually reachable),
that range is inconsistent, 0x2d is 45, so there is conflict between the
values and the irange_bitmask.
value-range.{h,cc} code differentiates between actually stored
irange_bitmask, which is that MASK 0xffffffffffffc000 VALUE 0x2d, and
semantic bitmask, which is what get_bitmask returns. That is
// The mask inherent in the range is calculated on-demand. For
// example, [0,255] does not have known bits set by default. This
// saves us considerable time, because setting it at creation incurs
// a large penalty for irange::set. At the time of writing there
// was a 5% slowdown in VRP if we kept the mask precisely up to date
// at all times. Instead, we default to -1 and set it when
// explicitly requested. However, this function will always return
// the correct mask.
//
// This also means that the mask may have a finer granularity than
// the range and thus contradict it. Think of the mask as an
// enhancement to the range. For example:
//
// [3, 1000] MASK 0xfffffffe VALUE 0x0
//
// 3 is in the range endpoints, but is excluded per the known 0 bits
// in the mask.
//
// See also the note in irange_bitmask::intersect.
irange_bitmask bm
= get_bitmask_from_range (type (), lower_bound (), upper_bound ());
if (!m_bitmask.unknown_p ())
bm.intersect (m_bitmask);
Now, get_bitmask_from_range here is MASK 0x1f VALUE 0x0 and it intersects
that with that MASK 0xffffffffffffc000 VALUE 0x2d.
Which triggers the ugly special case in irange_bitmask::intersect:
// If we have two known bits that are incompatible, the resulting
// bit is undefined. It is unclear whether we should set the entire
// range to UNDEFINED, or just a subset of it. For now, set the
// entire bitmask to unknown (VARYING).
if (wi::bit_and (~(m_mask | src.m_mask),
m_value ^ src.m_value) != 0)
{
unsigned prec = m_mask.get_precision ();
m_mask = wi::minus_one (prec);
m_value = wi::zero (prec);
}
so the semantic bitmask is actually MASK 0xffffffffffffffff VALUE 0x0.
Next, range_of_phi attempts to union it with the 0(3) PHI argument,
and during irange::union_ first adds the [0,0] to the subranges, so
[irange] long long unsigned int [0, 0][17, 17][25, 25] MASK 0xffffffffffffc000 VALUE 0x2d
and then goes on to irange::union_bitmask which does
if (m_bitmask == r.m_bitmask)
return false;
irange_bitmask bm = get_bitmask ();
irange_bitmask save = bm;
bm.union_ (r.get_bitmask ());
if (save == bm)
return false;
m_bitmask = bm;
if (save == get_bitmask ())
return false;
m_bitmask MASK 0xffffffffffffc000 VALUE 0x2d isn't the same as
r.m_bitmask MASK 0x0 VALUE 0x0, so we compute the semantic bitmask
(but note, not from the original range before union, but the modified one,
dunno if that isn't a problem as well), which is still the VARYING/unknown_p
one, union_ that with MASK 0x0 VALUE 0x0 and get still
MASK 0xffffffffffffffff VALUE 0x0, so don't update anything, the semantic
bitmask didn't change, so we are fine (not!, see later).
Except then we try to union with the third PHI argument. And, because the
edge to that comes only from case 8: label and there is a known difference
between the two, the argument is actually already from earlier replaced by
45(2) constant. So, irange::union_ adds the [45, 45] range to the list
of subranges, but voila, 45 is 0x2d and satisfies the stored
MASK 0xffffffffffffc000 VALUE 0x2d and so the semantic bitmask changed to
from MASK 0xffffffffffffffff VALUE 0x0 to MASK 0xffffffffffffc000 VALUE 0x2d
by that addition. Eventually, we just optimize this to
[irange] long long unsigned int [45, 45] because that is the only range
which satisfies the bitmask. And that is wrong, at runtime i_20 has
value 0.
The following patch attempts to detect this case where get_bitmask
turns some non-VARYING m_bitmask into VARYING one because of a conflict
and in that case makes sure m_bitmask is actually updated rather than
unmodified, so that later union_ doesn't cause problems.
I also wonder whether e.g. get_bitmask couldn't have special case for this
and if bm.intersect (m_bitmask); yields unknown_p from something not
originally unknown_p, perhaps chooses to just use get_bitmask_from_range
value and ignore the stored m_bitmask. Though, dunno how union_bitmask
in that case would figure out it needs to update m_bitmask.
2025-03-05 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/118953
* value-range.cc (irange::union_bitmask): Update m_bitmask if
get_bitmask () is unknown_p and m_bitmask is not even when the
semantic bitmask didn't change and returning false.
* gcc.dg/torture/pr118953.c: New test.
|
|
Fix regression introduced by r14-8710-g65b4cba9d6a9ff
PR libstdc++/119121
libstdc++-v3/ChangeLog:
* include/bits/ranges_util.h (__detail::__pair_like_convertible_from):
Use `_Tp` in `is_reference_v` check
* testsuite/std/ranges/subrange/tuple_like.cc: New tests for
pair-like conversion
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
|
|
For strict-alignment targets we can end up with BLKmode single-element
array types when the element type is unaligned. This confuses
type checking since the canonical type would have an aligned
element type and a non-BLKmode mode. The following simply ignores
the mode we assign to array types for this purpose, like we already
do for record and union types.
PR middle-end/97323
* tree.cc (gimple_canonical_types_compatible_p): Ignore
TYPE_MODE also for ARRAY_TYPE.
(verify_type): Likewise.
* gcc.dg/pr97323.c: New testcase.
|
|
ChangeLog:
* MAINTAINERS: Add myself.
|
|
This commit adds support for C++26's constexpr specialized memory
algorithms, introduced by P2283R2, P3508R0, P3369R0.
The uninitialized_default, value, copy, move and fill algorithms are
affected, in all of their variants (iterator-based, range-based and _n
versions.)
The changes are mostly mechanical -- add `constexpr` to a number of
signatures when compiling in C++26 and above modes. The internal helper
guard class for range algorithms instead can be marked unconditionally.
uninitialized_default_construct is implemented in terms of the
_Construct_novalue helper, which requires support for C++26's constexpr
placement new from the compiler (P2747R2, which GCC implements). We can
simply mark it as constexpr in C++26 language modes, even if the
compiler does not support P2747R2 (e.g. Clang 17/18), because C++23's
P2448R2 makes it OK to mark functions as constexpr even if they never
qualify, and other compilers implement this.
The only "real" change to the implementation of the algorithms is that
during constant evaluation I need to dispatch to a constexpr-friendly
version of them.
For each algorithm family I've added only one test to cover it and its
variants; the idea is to avoid too much repetition and simplify future
maintenance.
libstdc++-v3/ChangeLog:
* include/bits/ranges_uninitialized.h: Mark the specialized
memory algorithms as constexpr in C++26. Also mark the members
of the _DestroyGuard helper class.
* include/bits/stl_uninitialized.h: Ditto.
* include/bits/stl_construct.h: (_Construct_novalue) Mark it
as constexpr in C++26.
* include/bits/version.def (raw_memory_algorithms): Bump the
feature-testing macro for C++26.
* include/bits/version.h: Regenerate.
* testsuite/20_util/headers/memory/synopsis.cc: Add constexpr to
the uninitialized_* algorithms (when in C++26) in the test.
* testsuite/20_util/specialized_algorithms/feature_test_macro.cc:
New test.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/constexpr.cc:
New test.
* testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constexpr.cc:
New test.
* testsuite/20_util/specialized_algorithms/uninitialized_fill/constexpr.cc:
New test.
* testsuite/20_util/specialized_algorithms/uninitialized_move/constexpr.cc:
New test.
* testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constexpr.cc:
New test.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
|
|
differs [PR104684]
PR fortran/104684
gcc/fortran/ChangeLog:
* trans-array.cc (gfc_conv_expr_descriptor): Look at the
lang-specific akind and do a view convert when only the akind
attribute differs between pointer and allocatable array.
gcc/testsuite/ChangeLog:
* gfortran.dg/coarray/ptr_comp_6.f08: New test.
|
|
A checking assert triggers upon the following invalid code since
GCC 11:
=== cut here ===
class { a (struct b;
} struct b
=== cut here ===
The problem is that during error recovery, we call
set_identifier_type_value_with_scope for B in the global namespace, and
the checking assert added via r11-7228-g8f93e1b892850b fails.
This patch relaxes that assert to not fail if we've seen a parser error
(it a generalization of another fix done to that checking assert via
r11-7266-g24bf79f1798ad1).
PR c++/116740
gcc/cp/ChangeLog:
* name-lookup.cc (set_identifier_type_value_with_scope): Don't
fail assert with ill-formed input.
gcc/testsuite/ChangeLog:
* g++.dg/parse/crash80.C: New test.
|
|
modules.cc has apparently support for extensions and attempts to ensure
that if a module is compiled with those extensions enabled, sources which
use the module are compiled with the same extensions.
The only extension supported is SE_OPENMP right now.
And the use of the extension is keyed on streaming out or in OMP_CLAUSE
tree.
This is undesirable for several reasons.
OMP_CLAUSE is the only tree which can appear in the IL even without
-fopenmp/-fopenmp-simd/-fopenacc (when simd ("notinbranch") or
simd ("inbranch") attributes are used), and it can appear also in all
the 3 modes mentioned above. On the other side, with the exception of
arguments of attributes added e.g. for declare simd where no harm should
be done if -fopenmp/-fopenmp-simd isn't enabled later on, OMP_CLAUSE appears
in OMP_*_CLAUSES of OpenMP/OpenACC construct trees. And those construct
trees often have no clauses at all, so keying the extension on OMP_CLAUSE
doesn't catch many cases that should be caught.
Furthermore, for OpenMP we have 2 modes, -fopenmp-simd which parses some
OpenMP but constructs from that mostly OMP_SIMD and a few other cases,
and -fopenmp which includes that and far more on top of that; and there is
also -fopenacc.
So, this patch stops setting/requesting the extension on OMP_CLAUSE,
introduces 3 extensions rather than one (SE_OPENMP_SIMD, SE_OPENMP and
SE_OPENACC) and keyes those on OpenMP constructs from the -fopenmp-simd
subset, other OpenMP constructs and OpenACC constructs.
2025-03-05 Jakub Jelinek <jakub@redhat.com>
PR c++/119102
gcc/cp/
* module.cc (enum streamed_extensions): Add SE_OPENMP_SIMD
and SE_OPENACC, change value of SE_OPENMP and SE_BITS.
(CASE_OMP_SIMD_CODE, CASE_OMP_CODE, CASE_OACC_CODE): Define.
(trees_out::start): Don't set SE_OPENMP extension for OMP_CLAUSE.
Set SE_OPENMP_SIMD extension for CASE_OMP_SIMD_CODE, SE_OPENMP
for CASE_OMP_CODE and SE_OPENACC for CASE_OACC_CODE.
(trees_in::start): Don't fail for OMP_CLAUSE with missing
SE_OPENMP extension. Do fail for CASE_OMP_SIMD_CODE and missing
SE_OPENMP_SIMD extension, or CASE_OMP_CODE and missing SE_OPENMP
extension, or CASE_OACC_CODE and missing SE_OPENACC extension.
(module_state::write_readme): Write all of SE_OPENMP_SIMD, SE_OPENMP
and SE_OPENACC extensions.
(module_state::read_config): Diagnose missing -fopenmp, -fopenmp-simd
and/or -fopenacc depending on extensions used.
gcc/testsuite/
* g++.dg/modules/pr119102_a.H: New test.
* g++.dg/modules/pr119102_b.C: New test.
* g++.dg/modules/omp-3_a.C: New test.
* g++.dg/modules/omp-3_b.C: New test.
* g++.dg/modules/omp-3_c.C: New test.
* g++.dg/modules/omp-3_d.C: New test.
* g++.dg/modules/oacc-1_a.C: New test.
* g++.dg/modules/oacc-1_b.C: New test.
* g++.dg/modules/oacc-1_c.C: New test.
|
|
During the 118874 coro investigation I found a typo in a comment.
Fixed thusly.
2025-03-05 Jakub Jelinek <jakub@redhat.com>
* typeck.cc (check_return_expr): Fix comment typo, rom -> from.
|
|
ARRAY/POINTER/REFERENCE_TYPE [PR118787]
The following testcase IMO in violation of the P2552R3 paper doesn't
pedwarn on alignas applying to dependent types or alignas with dependent
argument.
tsubst was just ignoring TYPE_ATTRIBUTES.
The following patch fixes it for the POINTER/REFERENCE_TYPE and
ARRAY_TYPE cases, but perhaps we need to do the same also for other
types (INTEGER_TYPE/REAL_TYPE and the like). I guess I'll need to
construct more testcases.
2025-03-05 Jakub Jelinek <jakub@redhat.com>
PR c++/118787
* pt.cc (tsubst) <case ARRAY_TYPE>: Use return t; only if it doesn't
have any TYPE_ATTRIBUTES. Call apply_late_template_attributes.
<case POINTER_TYPE, case REFERENCE_TYPE>: Likewise. Formatting fix.
* g++.dg/cpp0x/alignas22.C: New test.
|
|
They could be incorrectly reordered with store instructions like st.b
because the RTL expression does not have a memory_operand or a (mem)
expression. The incorrect reorder has been observed in openh264 LTO
build.
Expand them to a (mem) expression instead of unspec to fix the issue.
Then we need to make loongarch_address_insns return 1 for
ADDRESS_REG_REG because the constraint "R" expects this behavior, or
the vldx instruction will be considered invalid by the register
allocate pass and turned to add.d + vld. Apply the ADDRESS_REG_REG
penalty in loongarch_address_cost instead, loongarch_rtx_costs should
also call loongarch_address_cost instead of loongarch_address_insns
then.
Closes: https://github.com/cisco/openh264/issues/3857
gcc/ChangeLog:
PR target/119084
* config/loongarch/lasx.md (UNSPEC_LASX_XVLDX): Remove.
(lasx_xvldx): Remove.
* config/loongarch/lsx.md (UNSPEC_LSX_VLDX): Remove.
(lsx_vldx): Remove.
* config/loongarch/simd.md (QIVEC): New define_mode_iterator.
(<simd_isa>_<x>vldx): New define_expand.
* config/loongarch/loongarch.cc (loongarch_address_insns_1): New
static function with most logic factored out from ...
(loongarch_address_insns): ... here. Call
loongarch_address_insns_1 with reg_reg_cost = 1.
(loongarch_address_cost): Call loongarch_address_insns_1 with
reg_reg_cost = la_addr_reg_reg_cost.
gcc/testsuite/ChangeLog:
PR target/119084
* gcc.target/loongarch/pr119084.c: New test.
|
|
|
|
Here gimplification got confused because extend_temps_r messed up the types
of the arms of a COND_EXPR.
PR c++/119073
gcc/cp/ChangeLog:
* call.cc (extend_temps_r): Preserve types of COND_EXPR arms.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/range-for39.C: New test.
|
|
For PR go/119098
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/654477
|
|
The problem was that we were not handling external dummy arguments
with -fc-prototypes-external. In looking at this, I found that we
were not warning about external procedures with different argument
lists. This can actually be legal (see the two test cases) but
creates a problem for the C prototypes: If we have something like
subroutine foo(a,n)
external a
if (n == 1) call a(1)
if (n == 2) call a(2,3)
end subroutine foo
then, pre-C23, we could just have written out the prototype as
void foo_ (void (*a) (), int *n);
but this is illegal in C23. What to do? I finally chose to warn
about the argument mismatch, with a new option. Warn only because the
code above is legal, but include in -Wall because such code seems highly
suspect. This option is also implied in -fc-prototypes-external. I also
put a warning in the generated header file in that case, so users
have a chance to see what is going on (especially since gcc now
defaults to C23).
gcc/fortran/ChangeLog:
PR fortran/119049
PR fortran/119074
* dump-parse-tree.cc (seen_conflict): New static varaible.
(gfc_dump_external_c_prototypes): Initialize it. If it was
set, write out a warning that -std=c23 will not work.
(write_proc): Move the work of actually writing out the
formal arglist to...
(write_formal_arglist): New function. Handle external dummy
parameters and their argument lists. If there were mismatched
arguments, output an empty argument list in pre-C23 style.
* gfortran.h (struct gfc_symbol): Add ext_dummy_arglist_mismatch
flag and formal_at.
* invoke.texi: Document -Wexternal-argument-mismatch.
* lang.opt: Put it in.
* resolve.cc (resolve_function): If warning about external
argument mismatches, build a formal from actual arglist the
first time around, and later compare and warn.
(resolve_call): Likewise
gcc/testsuite/ChangeLog:
PR fortran/119049
PR fortran/119074
* gfortran.dg/interface_55.f90: New test.
* gfortran.dg/interface_56.f90: New test.
|
|
gcc/
* doc/invoke.texi (AVR Optimization Options): New @subsubsection
for pure optimization options.
|
|
gcc/testsuite/ChangeLog:
* gcc.target/arm/pr68674.c: Use effective-target arm_arch_v7a
and arm_libc_fp_abi.
Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
|
|
gcc/ChangeLog:
* doc/extend.texi: Improve example for __builtin_bswap16.
|
|
Zen5 on some variants has false dependency on tzcnt, blsi, blsr and blsmsk
instructions. Those can be tested by the following benchmark
jh@shroud:~> cat ee.c
int
main()
{
int a = 10;
int b = 0;
for (int i = 0; i < 1000000000; i++)
{
asm volatile ("xor %0, %0": "=r" (b));
asm volatile (INST " %2, %0": "=r"(b): "0"(b),"r"(a));
asm volatile (INST " %2, %0": "=r"(b): "0"(b),"r"(a));
asm volatile (INST " %2, %0": "=r"(b): "0"(b),"r"(a));
asm volatile (INST " %2, %0": "=r"(b): "0"(b),"r"(a));
asm volatile (INST " %2, %0": "=r"(b): "0"(b),"r"(a));
asm volatile (INST " %2, %0": "=r"(b): "0"(b),"r"(a));
asm volatile (INST " %2, %0": "=r"(b): "0"(b),"r"(a));
asm volatile (INST " %2, %0": "=r"(b): "0"(b),"r"(a));
asm volatile (INST " %2, %0": "=r"(b): "0"(b),"r"(a));
asm volatile (INST " %2, %0": "=r"(b): "0"(b),"r"(a));
}
return 0;
}
jh@shroud:~> cat bmk.sh
gcc ee.c -DBREAK -DINST=\"$1\" -O2 ; time ./a.out ; gcc ee.c -DINST=\"$1\" -O2 ; time ./a.out
jh@shroud:~> sh bmk.sh tzcnt
real 0m0.886s
user 0m0.886s
sys 0m0.000s
real 0m0.886s
user 0m0.886s
sys 0m0.000s
jh@shroud:~> sh bmk.sh blsi
real 0m0.979s
user 0m0.979s
sys 0m0.000s
real 0m2.418s
user 0m2.418s
sys 0m0.000s
jh@shroud:~> sh bmk.sh blsr
real 0m0.986s
user 0m0.986s
sys 0m0.000s
real 0m2.422s
user 0m2.421s
sys 0m0.000s
jh@shroud:~> sh bmk.sh blsmsk
real 0m0.973s
user 0m0.973s
sys 0m0.000s
real 0m2.422s
user 0m2.422s
sys 0m0.000s
We already have runable that controls tzcnt together with lzcnt and popcnt.
Since it seems that only tzcnt is affected I added new tunable to control tzcnt
only. I also added splitters for blsi/blsr/blsmsk implemented analogously to
existing splitter for lzcnt.
The patch is neutral on SPEC. We produce blsi and blsr in some internal loops, but
they usually have same destination as source. However it is good to break the
dependency chain to avoid patogolical cases and it is quite cheap overall, so I
think we want to enable this for generic. I will send followup patch for this.
Bootstrapped/regtested x86_64-linux, will commit it shortly.
gcc/ChangeLog:
* config/i386/i386.h (TARGET_AVOID_FALSE_DEP_FOR_TZCNT): New macro.
(TARGET_AVOID_FALSE_DEP_FOR_BLS): New macro.
* config/i386/i386.md (*bmi_blsi_<mode>): Add splitter for false
dependency.
(*bmi_blsi_<mode>_ccno): Add splitter for false dependency.
(*bmi_blsi_<mode>_falsedep): New pattern.
(*bmi_blsmsk_<mode>): Add splitter for false dependency.
(*bmi_blsmsk_<mode>_falsedep): New pattern.
(*bmi_blsr_<mode>): Add splitter for false dependency.
(*bmi_blsr_<mode>_cmp): Add splitter for false dependency
(*bmi_blsr_<mode>_cmp_falsedep): New pattern.
* config/i386/x86-tune.def (X86_TUNE_AVOID_FALSE_DEP_FOR_TZCNT): New tune.
(X86_TUNE_AVOID_FALSE_DEP_FOR_BLS): New tune.
gcc/testsuite/ChangeLog:
* gcc.target/i386/blsi.c: New test.
* gcc.target/i386/blsmsk.c: New test.
* gcc.target/i386/blsr.c: New test.
|
|
PR fortran/103391
gcc/fortran/ChangeLog:
* trans-expr.cc (gfc_trans_assignment_1): Do not use poly assign
for pointer arrays on lhs (as it is done for allocatables
already).
gcc/testsuite/ChangeLog:
* gfortran.dg/assign_12.f90: New test.
|
|
The current implementation of fussion predicates misses some common
fussion cases on zen and more recent cores. I added knobs for
individual conditionals we test.
1) I split checks for fusing ALU with conditional operands when the ALU
has memory operand. This seems to be supported by zen3+ and by
tigerlake and coperlake (according to Agner Fog's manual)
2) znver4 and 5 supports fussion of ALU and conditional even if ALU has
memory and immediate operands.
This seems to be relatively important enabling 25% more fusions on
gcc bootstrap.
3) no CPU supports fusing when ALU contains IP relative memory
references. I added separate knob so we do not forger about this if
this gets supoorted later.
The patch does not solve the limitation of sched that fuse pairs must be
adjacent on imput and the first operation must be signle-set. Fixing
single-set is easy (I have separate patch for this), for non-adjacent
pairs we need bigger surgery.
To verify what CPU really does I made simpe test script.
jh@ryzen3:~> cat fuse-test.c
int b;
const int z = 0;
const int o = 1;
int
main()
{
int a = 1000000000;
int b;
int z = 0;
int o = 1;
asm volatile ("\n"
".L1234:\n"
"nop\n"
"subl %3, %0\n"
"movl %0, %1\n"
"cmpl %2, %1\n"
"movl %0, %1\n"
"test %1, %1\n"
"nop\n"
"jne .L1234":"=a"(a),
"=m"(b)
"=r"(b)
:
"m"(z),
"m"(o),
"i"(0),
"i"(1),
"0"(a)
);
}
jh@ryzen3:~> cat fuse-test.sh
EVENT=ex_ret_fused_instr
dotest()
{
gcc -O2 fuse-test.c $* -o fuse-cmp-imm-mem-nofuse
perf stat -e $EVENT ./fuse-cmp-imm-mem-nofuse 2>&1 | grep $EVENT
gcc -O2 fuse-test.c -DFUSE $* -o fuse-cmp-imm-mem-fuse
perf stat -e $EVENT ./fuse-cmp-imm-mem-fuse 2>&1 | grep $EVENT
}
echo ALU with immediate
dotest
echo ALU with memory
dotest -D MEM
echo ALU with IP relative memory
dotest -D MEM -D IPRELATIVE
echo CMP with immediate
dotest -D CMP
echo CMP with memory
dotest -D CMP -D MEM
echo CMP with memory and immediate
dotest -D CMP -D MEMIMM
echo CMP with IP relative memory
dotest -D CMP -D MEM -D IPRELATIVE
echo TEST
dotest -D TEST
On zen5 I get:
ALU with immediate
20,345 ex_ret_fused_instr:u
1,000,020,278 ex_ret_fused_instr:u
ALU with memory
20,367 ex_ret_fused_instr:u
1,000,020,290 ex_ret_fused_instr:u
ALU with IP relative memory
20,395 ex_ret_fused_instr:u
20,403 ex_ret_fused_instr:u
CMP with immediate
20,369 ex_ret_fused_instr:u
1,000,020,301 ex_ret_fused_instr:u
CMP with memory
20,314 ex_ret_fused_instr:u
1,000,020,341 ex_ret_fused_instr:u
CMP with memory and immediate
20,372 ex_ret_fused_instr:u
1,000,020,266 ex_ret_fused_instr:u
CMP with IP relative memory
20,382 ex_ret_fused_instr:u
20,369 ex_ret_fused_instr:u
TEST
20,346 ex_ret_fused_instr:u
1,000,020,301 ex_ret_fused_instr:u
IP relative memory seems to not be documented.
On zen3/4 I get:
ALU with immediate
20,263 ex_ret_fused_instr:u
1,000,020,051 ex_ret_fused_instr:u
ALU with memory
20,255 ex_ret_fused_instr:u
1,000,020,056 ex_ret_fused_instr:u
ALU with IP relative memory
20,253 ex_ret_fused_instr:u
20,266 ex_ret_fused_instr:u
CMP with immediate
20,264 ex_ret_fused_instr:u
1,000,020,052 ex_ret_fused_instr:u
CMP with memory
20,253 ex_ret_fused_instr:u
1,000,019,794 ex_ret_fused_instr:u
CMP with memory and immediate
20,260 ex_ret_fused_instr:u
20,264 ex_ret_fused_instr:u
CMP with IP relative memory
20,258 ex_ret_fused_instr:u
20,256 ex_ret_fused_instr:u
TEST
20,261 ex_ret_fused_instr:u
1,000,020,048 ex_ret_fused_instr:u
zen1 and 2 gets:
ALU with immediate
21,610 ex_ret_fus_brnch_inst:u
21,697 ex_ret_fus_brnch_inst:u
ALU with memory
21,479 ex_ret_fus_brnch_inst:u
21,747 ex_ret_fus_brnch_inst:u
ALU with IP relative memory
21,623 ex_ret_fus_brnch_inst:u
21,684 ex_ret_fus_brnch_inst:u
CMP with immediate
21,708 ex_ret_fus_brnch_inst:u
1,000,021,288 ex_ret_fus_brnch_inst:u
CMP with memory
21,689 ex_ret_fus_brnch_inst:u
1,000,004,270 ex_ret_fus_brnch_inst:u
CMP with memory and immediate
21,604 ex_ret_fus_brnch_inst:u
21,671 ex_ret_fus_brnch_inst:u
CMP with IP relative memory
21,589 ex_ret_fus_brnch_inst:u
21,602 ex_ret_fus_brnch_inst:u
TEST
21,600 ex_ret_fus_brnch_inst:u
1,000,021,233 ex_ret_fus_brnch_inst:u
I tested the patch on zen3 and zen5 and spec2k17 and it seems neutral, however
the number of fussion does go up.
Bootstrapped/regtested x86_64-linux, I plan to commit it tomorrow.
Honza
gcc/ChangeLog:
* config/i386/i386.h (TARGET_FUSE_ALU_AND_BRANCH_MEM): New macro.
(TARGET_FUSE_ALU_AND_BRANCH_MEM_IMM): New macro.
(TARGET_FUSE_ALU_AND_BRANCH_RIP_RELATIVE): New macro.
* config/i386/x86-tune-sched.cc (ix86_fuse_mov_alu_p): Support
non-single-set.
(ix86_macro_fusion_pair_p): Allow ALU which only clobbers;
be more careful about immediates; check TARGET_FUSE_ALU_AND_BRANCH_MEM,
TARGET_FUSE_ALU_AND_BRANCH_MEM_IMM, TARGET_FUSE_ALU_AND_BRANCH_RIP_RELATIVE;
verify that we never use unsigned checks with inc/dec.
* config/i386/x86-tune.def (X86_TUNE_FUSE_ALU_AND_BRANCH): New tune.
(X86_TUNE_FUSE_ALU_AND_BRANCH_MEM): New tune.
(X86_TUNE_FUSE_ALU_AND_BRANCH_MEM_IMM): New tune.
(X86_TUNE_FUSE_ALU_AND_BRANCH_RIP_RELATIVE): New tune.
|
|
We crash because we generate
{[0 ... 1]={.low=0, .high=1}, [1]={.low=0, .high=1}}
which output_constructor_regular_field doesn't want to see. This
happens since r9-1483: process_init_constructor_array can now create
a RANGE_EXPR. But the bug isn't in that patch; the problem is that
build_vec_init doesn't handle RANGE_EXPRs.
build_vec_init has a FOR_EACH_CONSTRUCTOR_ELT loop which populates
const_vec. In this case it loops over the elements of
{[0 ... 1]={.low=0, .high=1}}
but assumes that each element initializes one element. So after the
loop num_initialized_elts was 1, and then below:
HOST_WIDE_INT last = tree_to_shwi (maxindex);
if (num_initialized_elts <= last)
{
tree field = size_int (num_initialized_elts);
if (num_initialized_elts != last)
field = build2 (RANGE_EXPR, sizetype, field,
size_int (last));
CONSTRUCTOR_APPEND_ELT (const_vec, field, e);
}
we added the extra initializer.
It seemed convenient to use range_expr_nelts like below.
PR c++/109431
gcc/cp/ChangeLog:
* cp-tree.h (range_expr_nelts): Declare.
* init.cc (build_vec_init): If the CONSTRUCTOR's index is a
RANGE_EXPR, use range_expr_nelts to count how many elements
were initialized.
gcc/testsuite/ChangeLog:
* g++.dg/init/array67.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
When the input is already a subreg and we try to make a paradoxical
subreg out of it for copysign this can fail if it violates the subreg
relationship.
Use force_lowpart_subreg instead of lowpart_subreg to then force the
results to a register instead of ICEing.
gcc/ChangeLog:
PR target/118892
* config/aarch64/aarch64.md (copysign<GPF:mode>3): Use
force_lowpart_subreg instead of lowpart_subreg.
gcc/testsuite/ChangeLog:
PR target/118892
* gcc.target/aarch64/copysign-pr118892.c: New test.
|
|
libstdc++-v3/ChangeLog:
* doc/xml/manual/test.xml: Remove stray comma.
* doc/html/manual/test.html: Regenerate.
|
|
There was an embarrassing typo in the folding of BIT_NOT_EXPR for
POLY_INT_CSTs: it used - rather than ~ on the poly_int. Not sure
how that happened, but it might have been due to the way that
~x is implemented as -1 - x internally.
gcc/
PR tree-optimization/118976
* fold-const.cc (const_unop): Use ~ rather than - for BIT_NOT_EXPR.
* config/aarch64/aarch64.cc (aarch64_test_sve_folding): New function.
(aarch64_run_selftests): Run it.
|
|
The following testcase is miscompiled on powerpc64le-linux starting with
r15-6777. During combine we see:
(set (reg:SI 134)
(ior:SI (ge:SI (reg:CCFP 128)
(const_int 0 [0]))
(lt:SI (reg:CCFP 128)
(const_int 0 [0]))))
The simplify_logical_relational_operation code (in its current form)
was written with arithmetic rather than CC modes in mind. Since CCFP
is a CC mode, it fails the HONOR_NANS check, and so the function assumes
that ge | lt => true.
If one comparison is unsigned then it should be safe to assume that
the other comparison is also unsigned, even for CC modes, since the
optimisation checks that the comparisons are between the same operands.
For the other cases, we can only safely fold comparisons of CC mode
values if the result is always-true (15) or always-false (0).
It turns out that the original testcase for PR117186, which ran at -O,
was relying on the old behaviour for some of the functions. It needs
4-instruction combinations, and so -fexpensive-optimizations, to pass
in its intended form.
gcc/
PR rtl-optimization/119002
* simplify-rtx.cc
(simplify_context::simplify_logical_relational_operation): Handle
comparisons between CC values. If there is no evidence that the
CC values are unsigned, restrict the fold to always-true or
always-false results.
gcc/testsuite/
* gcc.c-torture/execute/ieee/pr119002.c: New test.
* gcc.target/aarch64/pr117186.c: Run at -O2 rather than -O.
Co-authored-by: Jakub Jelinek <jakub@redhat.com>
|
|
Uros' r15-7793 fixed this PR as well, I'm just committing tests
from the PR so that it can be closed.
2025-03-04 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/119071
* gcc.dg/pr119071.c: New test.
* gcc.c-torture/execute/pr119071.c: New test.
|
|
PR fortran/77872
gcc/fortran/ChangeLog:
* trans-expr.cc (gfc_get_tree_for_caf_expr): Pick up token from
decl when it is present there for class types.
gcc/testsuite/ChangeLog:
* gfortran.dg/coarray/class_1.f90: New test.
|
|
PR fortran/77872
gcc/fortran/ChangeLog:
* trans-expr.cc (gfc_conv_procedure_call): Use attr instead of
doing type check and branching for BT_CLASS.
|
|
When we vectorize a .COND_ADD reduction and apply the single-use-def
cycle optimization we can end up chosing the wrong else value for
subsequent .COND_ADD. The following rectifies this.
PR tree-optimization/119096
* tree-vect-loop.cc (vect_transform_reduction): Use the
correct else value for .COND_fn.
* gcc.dg/vect/pr119096.c: New testcase.
|
|
The bug-3.c would like to check the slli a[0-9]+, a[0-9]+, 33 for the
big poly int handling. But the underlying insn may change to slli 1
+ slli 32 with sorts of optimization. Thus, update the asm check to
function body check with above slli 1 + slli 32 series.
The below test suites are passed for this patch.
* The rv64gcv fully regression test.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/bug-3.c: Update asm check to
function body check.
Signed-off-by: Pan Li <pan2.li@intel.com>
|
|
|
|
gcc/po/
* be.po, da.po, de.po, el.po, es.po, fi.po, fr.po, hr.po, id.po,
ja.po, ka.po, nl.po, ru.po, sr.po, sv.po, tr.po, uk.po, vi.po,
zh_CN.po, zh_TW.po: Update.
libcpp/po/
* be.po, ca.po, da.po, de.po, el.po, eo.po, es.po, fi.po, fr.po,
id.po, ja.po, ka.po, nl.po, pt_BR.po, ro.po, ru.po, sr.po, sv.po,
tr.po, uk.po, vi.po, zh_CN.po, zh_TW.po: Update.
|
|
PR fortran/101577
gcc/fortran/ChangeLog:
* symbol.cc (verify_bind_c_derived_type): Generate error message
for derived type with no components in standard conformance mode,
indicating that this is a GNU extension.
gcc/testsuite/ChangeLog:
* gfortran.dg/empty_derived_type.f90: Adjust dg-options.
* gfortran.dg/empty_derived_type_2.f90: New test.
|
|
Refactor the switcher classes into two separate classes:
- sve_alignment_switcher takes the alignment switching functionality,
and is used only for ABI correctness when defining sve structure
types.
- aarch64_target_switcher takes the rest of the functionality of
aarch64_simd_switcher and sve_switcher, and gates simd/sve specific
parts upon the specified feature flags.
Additionally, aarch64_target_switcher now adds dependencies of the
specified flags (which adds +fcma and +bf16 to some intrinsic
declarations), and unsets current_target_pragma.
This last change fixes an internal bug where we would sometimes add a
user specified target pragma (stored in current_target_pragma) on top of
an internally specified target architecture while initialising
intrinsics with `#pragma GCC aarch64 "arm_*.h"`. As far as I can tell, this
has no visible impact at the moment. However, the unintended target
feature combinations lead to unwanted behaviour in an under-development
patch.
This also fixes a missing Makefile dependency, which was due to
aarch64-sve-builtins.o incorrectly depending on the undefined $(REG_H).
The correct $(REGS_H) dependency is added to the switcher's new source
location.
gcc/ChangeLog:
* common/config/aarch64/aarch64-common.cc
(struct aarch64_extension_info): Add field.
(aarch64_get_required_features): New.
* config/aarch64/aarch64-builtins.cc
(aarch64_simd_switcher::aarch64_simd_switcher): Rename to...
(aarch64_target_switcher::aarch64_target_switcher): ...this,
and extend to handle sve, nosimd and target pragmas.
(aarch64_simd_switcher::~aarch64_simd_switcher): Rename to...
(aarch64_target_switcher::~aarch64_target_switcher): ...this,
and extend to handle sve, nosimd and target pragmas.
(handle_arm_acle_h): Use aarch64_target_switcher.
(handle_arm_neon_h): Rename switcher and pass explicit flags.
(aarch64_general_init_builtins): Ditto.
* config/aarch64/aarch64-protos.h
(class aarch64_simd_switcher): Rename to...
(class aarch64_target_switcher): ...this, and add new members.
(aarch64_get_required_features): New prototype.
* config/aarch64/aarch64-sve-builtins.cc
(sve_switcher::sve_switcher): Delete
(sve_switcher::~sve_switcher): Delete
(sve_alignment_switcher::sve_alignment_switcher): New
(sve_alignment_switcher::~sve_alignment_switcher): New
(register_builtin_types): Use alignment switcher
(init_builtins): Rename switcher.
(handle_arm_neon_sve_bridge_h): Ditto.
(handle_arm_sme_h): Ditto.
(handle_arm_sve_h): Ditto, and use alignment switcher.
* config/aarch64/aarch64-sve-builtins.h
(class sve_switcher): Delete.
(class sme_switcher): Delete.
(class sve_alignment_switcher): New.
* config/aarch64/t-aarch64 (aarch64-builtins.o): Add $(REGS_H).
(aarch64-sve-builtins.o): Remove $(REG_H).
|
|
The code in gcc.target/unsigned-extend-1.c really should not need an
unsigned extension operations when the optimizers are used. For Arm
and thumb2 that is indeed the case, but for thumb1 code it gets more
complicated as there are too many instructions for combine to look at.
For thumb1 we end up with two redundant zero_extend patterns which are
not removed: the first after the subtract instruction and the second of
the final boolean result.
We can partially fix this (for the second case above) by adding a new
split pattern for LEU and GEU patterns which work because the two
instructions for the [LG]EU pattern plus the redundant extension
instruction are combined into a single insn, which we can then split
using the 3->2 method back into the two insns of the [LG]EU sequence.
Because we're missing the optimization for all thumb1 cases (not just
those architectures with UXTB), I've adjust the testcase to detect all
the idioms that we might use for zero-extending a value, namely:
UXTB
AND ...#255 (in thumb1 this would require a register to hold 255)
LSL ... #24; LSR ... #24
but I've also marked this test as XFAIL for thumb1 because we can't yet
eliminate the first of the two extend instructions.
gcc/
* config/arm/thumb1.md (split patterns for GEU and LEU): New.
gcc/testsuite:
* gcc.target/arm/unsigned-extend-1.c: Expand check for any
insn suggesting a zero-extend. XFAIL for thumb1 code.
|
|
This reverts commit f1c30c6213fb228f1e8b5973d10c868b834a4acd.
|
|
Reverse negative logic in !a ? b : c to become a ? c : b.
No functional changes.
gcc/ChangeLog:
* combine.cc (distribute_notes):
Reverse negative logic in ternary operators.
|
|
i3 [PR118739]
The combine pass is trying to combine:
Trying 16, 22, 21 -> 23:
16: r104:QI=flags:CCNO>0
22: {r120:QI=r104:QI^0x1;clobber flags:CC;}
REG_UNUSED flags:CC
21: r119:QI=flags:CCNO<=0
REG_DEAD flags:CCNO
23: {r110:QI=r119:QI|r120:QI;clobber flags:CC;}
REG_DEAD r120:QI
REG_DEAD r119:QI
REG_UNUSED flags:CC
and creates the following two insn sequence:
modifying insn i2 22: r104:QI=flags:CCNO>0
REG_DEAD flags:CC
deferring rescan insn with uid = 22.
modifying insn i3 23: r110:QI=flags:CCNO<=0
REG_DEAD flags:CC
deferring rescan insn with uid = 23.
where the REG_DEAD note in i2 is not correct, because the flags
register is still referenced in i3. In try_combine() megafunction,
we have this part:
--cut here--
/* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3. */
if (i3notes)
distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL,
elim_i2, elim_i1, elim_i0);
if (i2notes)
distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL,
elim_i2, elim_i1, elim_i0);
if (i1notes)
distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL,
elim_i2, local_elim_i1, local_elim_i0);
if (i0notes)
distribute_notes (i0notes, i0, i3, newi2pat ? i2 : NULL,
elim_i2, elim_i1, local_elim_i0);
if (midnotes)
distribute_notes (midnotes, NULL, i3, newi2pat ? i2 : NULL,
elim_i2, elim_i1, elim_i0);
--cut here--
where the compiler distributes REG_UNUSED note from i2:
22: {r120:QI=r104:QI^0x1;clobber flags:CC;}
REG_UNUSED flags:CC
via distribute_notes() using the following:
--cut here--
/* Otherwise, if this register is used by I3, then this register
now dies here, so we must put a REG_DEAD note here unless there
is one already. */
else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3))
&& ! (REG_P (XEXP (note, 0))
? find_regno_note (i3, REG_DEAD,
REGNO (XEXP (note, 0)))
: find_reg_note (i3, REG_DEAD, XEXP (note, 0))))
{
PUT_REG_NOTE_KIND (note, REG_DEAD);
place = i3;
}
--cut here--
Flags register is used in I3, but there already is a REG_DEAD note in I3.
The above condition doesn't trigger and continues in the "else" part where
REG_DEAD note is put to I2. The proposed solution corrects the above
logic to trigger every time the register is referenced in I3, avoiding the
"else" part.
PR rtl-optimization/118739
gcc/ChangeLog:
* combine.cc (distribute_notes) <case REG_UNUSED>: Correct the
logic when the register is used by I3.
gcc/testsuite/ChangeLog:
* gcc.target/i386/pr118739.c: New test.
|
|
Since we construct arithmetic jump functions even when there is a
type conversion in between the operation encoded in the jump function
and when it is passed in a call argument, the IPA propagation phase
must also perform the operation and conversion in two steps. IPA-VR
had actually been doing it even before for binary operations but, as
PR 118756 exposes, not in the case on unary operations. This patch
adds the necessary step to rectify that.
Like in the scalar constant case, we depend on
expr_type_first_operand_type_p to determine the type of the result of
the arithmetic operation. On top this, the patch special-cases
ABSU_EXPR because it looks useful an so that the PR testcase exercises
the added code-path. This seems most appropriate for stage 4, long
term we should probably stream the types, probably after also encoding
them with a string of expr_eval_op rather than what we have today.
A check for expr_type_first_operand_type_p was also missing in the
handling of binary ops and the intermediate value_range was
initialized with a wrong type, so I also fixed this.
gcc/ChangeLog:
2025-02-24 Martin Jambor <mjambor@suse.cz>
PR ipa/118785
* ipa-cp.cc (ipa_vr_intersect_with_arith_jfunc): Handle non-conversion
unary operations separately before doing any conversions. Check
expr_type_first_operand_type_p for non-unary operations too. Fix type
of op_res.
gcc/testsuite/ChangeLog:
2025-02-24 Martin Jambor <mjambor@suse.cz>
PR ipa/118785
* g++.dg/lto/pr118785_0.C: New test.
|
|
We are detecting a cycle as double reduction where the inner loop
cycle has extra out-of-loop uses. This clashes at least with
assumptions from the SLP discovery code which says the cycle
isn't reachable from another SLP instance. It also was not intended
to support this case, in fact with GCC 14 we seem to generate wrong
code here.
PR tree-optimization/119057
* tree-vect-loop.cc (check_reduction_path): Add argument
specifying whether we're analyzing the inner loop of a
double reduction. Do not allow extra uses outside of the
double reduction cycle in this case.
(vect_is_simple_reduction): Adjust.
* gcc.dg/vect/pr119057.c: New testcase.
|
|
odr_types_equivalent_p can end up using TYPE_PRECISION on vector
types which is a no-go. The following instead uses TYPE_VECTOR_SUBPARTS
for vector types so we also end up comparing the number of vector elements.
PR ipa/119067
* ipa-devirt.cc (odr_types_equivalent_p): Check
TYPE_VECTOR_SUBPARTS for vectors.
* g++.dg/lto/pr119067_0.C: New testcase.
* g++.dg/lto/pr119067_1.C: Likewise.
|
|
Fix a regression were adding a temporary variable inserted a copy of the
argument to the elemental function. That copy was then later used to
free allocated memory, but the freeing was not tracked in the source
array correctly.
PR fortran/118747
gcc/fortran/ChangeLog:
* trans-array.cc (gfc_trans_array_ctor_element): Remove copy to
temporary variable.
* trans-expr.cc (gfc_conv_procedure_call): Use references to
array members instead of copies when freeing after use.
Formatting fix.
gcc/testsuite/ChangeLog:
* gfortran.dg/alloc_comp_auto_array_4.f90: New test.
|
|
|