Jakub Jelinek [Fri, 6 Dec 2024 10:00:52 +0000 (11:00 +0100)]
Use new RAW_DATA_{U,S}CHAR_ELT macros in the middle-end and C FE
During the patch review of the C++ #embed optimization, Jason asked for
a macro for the common
((const unsigned char *) RAW_DATA_POINTER (value))[i]
and ditto with signed char patterns which appear in a lot of places.
In the just committed patch I've added
+#define RAW_DATA_UCHAR_ELT(NODE, I) \
+ (((const unsigned char *) RAW_DATA_POINTER (NODE))[I])
+#define RAW_DATA_SCHAR_ELT(NODE, I) \
+ (((const signed char *) RAW_DATA_POINTER (NODE))[I])
macros for that in tree.h.
The following patch is just a cleanup to use those macros where appropriate.
2024-12-06 Jakub Jelinek <jakub@redhat.com>
gcc/
* gimplify.cc (gimplify_init_ctor_eval): Use RAW_DATA_UCHAR_ELT
macro.
* gimple-fold.cc (fold_array_ctor_reference): Likewise.
* tree-pretty-print.cc (dump_generic_node): Use RAW_DATA_UCHAR_ELT
and RAW_DATA_SCHAR_ELT macros.
* fold-const.cc (fold): Use RAW_DATA_UCHAR_ELT macro.
gcc/c/
* c-parser.cc (c_parser_get_builtin_args, c_parser_expression,
c_parser_expr_list): Use RAW_DATA_UCHAR_ELT macro.
* c-typeck.cc (digest_init): Use RAW_DATA_UCHAR_ELT and
RAW_DATA_SCHAR_ELT macros.
(add_pending_init, maybe_split_raw_data): Use RAW_DATA_UCHAR_ELT
macro.
Richard Biener [Thu, 5 Dec 2024 12:47:36 +0000 (13:47 +0100)]
More duplicates reported by genmatch
Here are a bit less obvious cases of duplicate, mostly of the
form (op (op:c @0 @1) (op:c @0 @1)) where it's enough to have
one :c to get all relevant cases.
* match.pd: Remove redundant :c, reported by genmatch as
duplicate patterns.
Richard Biener [Thu, 5 Dec 2024 12:24:27 +0000 (13:24 +0100)]
Remove some duplicates reported by genmatch
genmatch currently has a difficulty to decide whether a duplicate
structural match is really duplicate as uses of captures within
predicates or in C code can be order dependent. For example
a reported duplicate results in
where the difference is only in _q20 and _q21 being swapped but
that resulting in a call to bitwise_inverted_equal_p (_p1, X)
with X once _q20 and once _q21. That is, we treat bare
captures as equal for reporting duplicates.
Due to bitwise_inverted_equal_p there are meanwhile a _lot_ of
duplicates reported that are not actual duplicates.
The following removes some that are though, as the operands are
only passed to types_match.
* match.pd (.SAT_ADD patterns using IFN_ADD_OVERFLOW): Remove :c that
only causes duplicate patterns.
Thomas Schwinge [Mon, 2 Dec 2024 14:06:58 +0000 (15:06 +0100)]
'gcc/config/nvptx/t-nvptx': Don't use the 'shell' function of 'make'
The exit status of the command invoked in a 'Makefile' via '$(shell [...])'
effectively gets discarded (unless explicitly checking the GNU Make 4.2+
'.SHELLSTATUS' variable or jumping through other hoops). In order to be able
to catch errors in what the 'shell' function invokes, let's make things
explicit: similar to how 'gcc/config/avr/t-avr' is doing with 't-multilib-avr',
for example.
gcc/
* config/nvptx/t-nvptx (multilib_matches): Don't use the 'shell'
function of 'make'.
* config/nvptx/gen-multilib-matches.sh: Adjust.
Thomas Schwinge [Wed, 4 Dec 2024 21:37:17 +0000 (22:37 +0100)]
nvptx: Tag '-misa=[...]', '-mptx=[...]' as 'Negative' of themselves [PR117916]
This issue is similar to what a year ago I resolved for GCN in PR112669
"GCN: wrong 'LIBRARY_PATH' in presence of several different '-march=[...]' flags".
Given the current standard nvptx configuration, we get:
This should print 'mgomp'. Otherwise, for OpenMP offloading compilation
the wrong (non-'mgomp') multilib is linked in ('.'), and linking fails
due to 'unresolved symbol __nvptx_uni'.
PR target/117916
gcc/
* config/nvptx/nvptx.opt (misa=, mptx=): Tag as 'Negative' of
themselves.
PTX '%dynamic_smem_size' was "Introduced in PTX ISA version 4.1", and
"Requires 'sm_20' or higher". Given that GCC/nvptx generally supports
'sm_20', only the PTX ISA version matters here, and that's all fine if
just using GCC's defaults. Follow-up to
commit e9a19ead498fcc89186b724c6e76854f7751a89b
"openmp, nvptx: low-lat memory access traits".
The motivation of the 'gimple_fold_builtin_acc_on_device' change in
commit 3269a722b7a03613e9c4e2862bc5088c4a17cc11
"Fortran: Use OpenACC's acc_on_device builtin, fix OpenMP' __builtin_is_initial_device"
is unclear, and it unnecessarily diverges GCC's (default)
'--disable-offload-targets' vs. '--enable-offload-targets=[...]'
configurations.
PR testsuite/82250
gcc/
* gimple-fold.cc (gimple_fold_builtin_acc_on_device): Revert last
change.
libgomp/
* testsuite/libgomp.oacc-c-c++-common/routine-nohost-1.c: Revert
last change.
Richard Biener [Fri, 6 Dec 2024 08:37:35 +0000 (09:37 +0100)]
testsuite/117714 - gcc.dg/vect/slp-reduc-4.c FAILs on 32-bit SPARC
The testcase tries to ensure we can elide all permutations when
vectorizing a MAX reduction. For SPARC the issue is that the
MAX reduction isn't supported and since we're trying to fall back
to single-lane SLP the dumps contain VEC_PERM_EXPR for the
interleaving permute lowering. Before all-SLP that wouldn't
be in the dumps when doing non-SLP, but eventually we'd fail to
vectorize so no VEC_PERM_EXPRs would be in the dumps either.
The following adds vect_no_int_min_max to the set of xfails for
this particular scan as well, like the existing check for vectorizing.
PR testsuite/117714
* gcc.dg/vect/slp-reduc-4.c: Add vect_no_int_min_max to the
XFAIL for the VEC_PERM_EXPR scan.
Jakub Jelinek [Fri, 6 Dec 2024 08:09:12 +0000 (09:09 +0100)]
libcpp, c++: Optimize initializers using #embed in C++
This patch adds similar optimizations to the C++ FE as have been
implemented earlier in the C FE.
The libcpp hunk enables use of CPP_EMBED token even for C++, not just
C; the preprocessor guarantees there is always a CPP_NUMBER CPP_COMMA
before CPP_EMBED and CPP_COMMA CPP_NUMBER after it which simplifies
parsing (unless #embed is more than 2GB, in that case it could be
CPP_NUMBER CPP_COMMA CPP_EMBED CPP_COMMA CPP_EMBED CPP_COMMA CPP_EMBED
CPP_COMMA CPP_NUMBER etc. with each CPP_EMBED covering at most INT_MAX
bytes).
Similarly to the C patch, this patch parses it into RAW_DATA_CST tree
in the braced initializers (and from there peels into INTEGER_CSTs unless
it is an initializer of an std::byte array or integral array with CHAR_BIT
element precision), parses CPP_EMBED in cp_parser_expression into just
the last INTEGER_CST in it because I think users don't need millions of
-Wunused-value warnings because they did useless
int a = (
#embed "megabyte.dat"
);
and so most of the inner INTEGER_CSTs would be there just for the warning,
and in the rest of contexts like template argument list, function argument
list, attribute argument list, ...) parse it into a sequence of INTEGER_CSTs
(I wrote a range/iterator classes to simplify that).
My dumb
cat embed-11.c
constexpr unsigned char a[] = {
#embed "cc1plus"
};
const unsigned char *b = a;
testcase where cc1plus is 492329008 bytes long when configured
--enable-checking=yes,rtl,extra against recent binutils with .base64 gas
support results in:
time ./xg++ -B ./ -S -O2 embed-11.c
real 0m4.350s
user 0m2.427s
sys 0m0.830s
time ./xg++ -B ./ -c -O2 embed-11.c
real 0m6.932s
user 0m6.034s
sys 0m0.888s
(compared to running out of memory or very long compilation).
On a shorter inclusion,
cat embed-12.c
constexpr unsigned char a[] = {
#embed "xg++"
};
const unsigned char *b = a;
where xg++ is 15225904 bytes long, this takes using GCC with the #embed
patchset except for this patch:
time ~/src/gcc/obj36/gcc/xg++ -B ~/src/gcc/obj36/gcc/ -S -O2 embed-12.c
real 0m33.190s
user 0m32.327s
sys 0m0.790s
and with this patch:
time ./xg++ -B ./ -S -O2 embed-12.c
real 0m0.118s
user 0m0.090s
sys 0m0.028s
The patch doesn't change anything on what the first patch in the series
introduces even for C++, namely that #embed is expanded (actually or as if)
into a sequence of literals like
127,69,76,70,2,1,1,3,0,0,0,0,0,0,0,0,2,0,62,0,1,0,0,0,80,211,64,0,0,0,0,0,64,0,0,0,0,0,0,0,8,253
and so each element has int type.
That is how I believe it is in C23, and the different versions of the
C++ P1967 paper specified there some casts, P1967R12 in particular
"Otherwise, the integral constant expression is the value of std::fgetc’s return is cast
to unsigned char."
but please see
https://github.com/llvm/llvm-project/pull/97274#issuecomment-2230929277
comment and whether we really want the preprocessor to preprocess it for
C++ as (or as-if)
static_cast<unsigned char>(127),static_cast<unsigned char>(69),static_cast<unsigned char>(76),static_cast<unsigned char>(70),static_cast<unsigned char>(2),...
i.e. 9 tokens per byte rather than 2, or
(unsigned char)127,(unsigned char)69,...
or
((unsigned char)127),((unsigned char)69),...
etc.
Without a literal suffix for unsigned char constant literals it is horrible,
plus the incompatibility between C and C++. Sure, we could use the magic
form more often for C++ to save the size and do the 9 or how many tokens
form only for the boundary constants and use #embed "." __gnu__::__base64__("...")
for what is in between if there are at least 2 tokens inside of it.
E.g. (unsigned char)127 vs. static_cast<unsigned char>(127) behaves
differently if there is constexpr long long p[] = { ... };
...
#embed __FILE__
[p]
2024-12-06 Jakub Jelinek <jakub@redhat.com>
libcpp/
* files.cc (finish_embed): Use CPP_EMBED even for C++.
gcc/
* tree.h (RAW_DATA_UCHAR_ELT, RAW_DATA_SCHAR_ELT): Define.
gcc/cp/ChangeLog:
* cp-tree.h (class raw_data_iterator): New type.
(class raw_data_range): New type.
* parser.cc (cp_parser_postfix_open_square_expression): Handle
parsing of CPP_EMBED.
(cp_parser_parenthesized_expression_list): Likewise. Use
cp_lexer_next_token_is.
(cp_parser_expression): Handle parsing of CPP_EMBED.
(cp_parser_template_argument_list): Likewise.
(cp_parser_initializer_list): Likewise.
(cp_parser_oacc_clause_tile): Likewise.
(cp_parser_omp_tile_sizes): Likewise.
* pt.cc (tsubst_expr): Handle RAW_DATA_CST.
* constexpr.cc (reduced_constant_expression_p): Likewise.
(raw_data_cst_elt): New function.
(find_array_ctor_elt): Handle RAW_DATA_CST.
(cxx_eval_array_reference): Likewise.
* typeck2.cc (digest_init_r): Emit -Wnarrowing and/or -Wconversion
diagnostics.
(process_init_constructor_array): Handle RAW_DATA_CST.
* decl.cc (maybe_deduce_size_from_array_init): Likewise.
(is_direct_enum_init): Fail for RAW_DATA_CST.
(cp_maybe_split_raw_data): New function.
(consume_init): New function.
(reshape_init_array_1): Add VECTOR_P argument. Handle RAW_DATA_CST.
(reshape_init_array): Adjust reshape_init_array_1 caller.
(reshape_init_vector): Likewise.
(reshape_init_class): Handle RAW_DATA_CST.
(reshape_init_r): Likewise.
gcc/testsuite/
* c-c++-common/cpp/embed-22.c: New test.
* c-c++-common/cpp/embed-23.c: New test.
* g++.dg/cpp/embed-4.C: New test.
* g++.dg/cpp/embed-5.C: New test.
* g++.dg/cpp/embed-6.C: New test.
* g++.dg/cpp/embed-7.C: New test.
* g++.dg/cpp/embed-8.C: New test.
* g++.dg/cpp/embed-9.C: New test.
* g++.dg/cpp/embed-10.C: New test.
* g++.dg/cpp/embed-11.C: New test.
* g++.dg/cpp/embed-12.C: New test.
* g++.dg/cpp/embed-13.C: New test.
* g++.dg/cpp/embed-14.C: New test.
Jennifer Schmitz [Fri, 15 Nov 2024 15:45:59 +0000 (07:45 -0800)]
SVE intrinsics: Fold calls with pfalse predicate.
If an SVE intrinsic has predicate pfalse, we can fold the call to
a simplified assignment statement: For _m predication, the LHS can be assigned
the operand for inactive values and for _z, we can assign a zero vector.
For _x, the returned values can be arbitrary and as suggested by
Richard Sandiford, we fold to a zero vector.
For example,
svint32_t foo (svint32_t op1, svint32_t op2)
{
return svadd_s32_m (svpfalse_b (), op1, op2);
}
can be folded to lhs = op1, such that foo is compiled to just a RET.
For implicit predication, a case distinction is necessary:
Intrinsics that read from memory can be folded to a zero vector.
Intrinsics that write to memory or prefetch can be folded to a no-op.
Other intrinsics need case-by-case implemenation, which we added in
the corresponding svxxx_impl::fold.
We implemented this optimization during gimple folding by calling a new method
gimple_folder::fold_pfalse from gimple_folder::fold, which covers the generic
cases described above.
We tested the new behavior for each intrinsic with all supported predications
and data types and checked the produced assembly. There is a test file
for each shape subclass with scan-assembler-times tests that look for
the simplified instruction sequences, such as individual RET instructions
or zeroing moves. There is an additional directive counting the total number of
functions in the test, which must be the sum of counts of all other
directives. This is to check that all tested intrinsics were optimized.
Some few intrinsics were not covered by this patch:
- svlasta and svlastb already have an implementation to cover a pfalse
predicate. No changes were made to them.
- svld1/2/3/4 return aggregate types and were excluded from the case
that folds calls with implicit predication to lhs = {0, ...}.
- svst1/2/3/4 already have an implementation in svstx_impl that precedes
our optimization, such that it is not triggered.
The patch was bootstrapped and regtested on aarch64-linux-gnu, no regression.
OK for mainline?
Signed-off-by: Jennifer Schmitz <jschmitz@nvidia.com>
gcc/ChangeLog:
PR target/106329
* config/aarch64/aarch64-sve-builtins-base.cc
(svac_impl::fold): Add folding if pfalse predicate.
(svadda_impl::fold): Likewise.
(class svaddv_impl): Likewise.
(class svandv_impl): Likewise.
(svclast_impl::fold): Likewise.
(svcmp_impl::fold): Likewise.
(svcmp_wide_impl::fold): Likewise.
(svcmpuo_impl::fold): Likewise.
(svcntp_impl::fold): Likewise.
(class svcompact_impl): Likewise.
(class svcvtnt_impl): Likewise.
(class sveorv_impl): Likewise.
(class svminv_impl): Likewise.
(class svmaxnmv_impl): Likewise.
(class svmaxv_impl): Likewise.
(class svminnmv_impl): Likewise.
(class svorv_impl): Likewise.
(svpfirst_svpnext_impl::fold): Likewise.
(svptest_impl::fold): Likewise.
(class svsplice_impl): Likewise.
* config/aarch64/aarch64-sve-builtins-sve2.cc
(class svcvtxnt_impl): Likewise.
(svmatch_svnmatch_impl::fold): Likewise.
* config/aarch64/aarch64-sve-builtins.cc
(is_pfalse): Return true if tree is pfalse.
(gimple_folder::fold_pfalse): Fold calls with pfalse predicate.
(gimple_folder::fold_call_to): Fold call to lhs = t for given tree t.
(gimple_folder::fold_to_stmt_vops): Helper function that folds the
call to given stmt and adjusts virtual operands.
(gimple_folder::fold): Call fold_pfalse.
* config/aarch64/aarch64-sve-builtins.h (is_pfalse): Declare is_pfalse.
gcc/testsuite/ChangeLog:
PR target/106329
* gcc.target/aarch64/pfalse-binary_0.h: New test.
* gcc.target/aarch64/pfalse-unary_0.h: New test.
* gcc.target/aarch64/sve/pfalse-binary.c: New test.
* gcc.target/aarch64/sve/pfalse-binary_int_opt_n.c: New test.
* gcc.target/aarch64/sve/pfalse-binary_opt_n.c: New test.
* gcc.target/aarch64/sve/pfalse-binary_opt_single_n.c: New test.
* gcc.target/aarch64/sve/pfalse-binary_rotate.c: New test.
* gcc.target/aarch64/sve/pfalse-binary_uint64_opt_n.c: New test.
* gcc.target/aarch64/sve/pfalse-binary_uint_opt_n.c: New test.
* gcc.target/aarch64/sve/pfalse-binaryxn.c: New test.
* gcc.target/aarch64/sve/pfalse-clast.c: New test.
* gcc.target/aarch64/sve/pfalse-compare_opt_n.c: New test.
* gcc.target/aarch64/sve/pfalse-compare_wide_opt_n.c: New test.
* gcc.target/aarch64/sve/pfalse-count_pred.c: New test.
* gcc.target/aarch64/sve/pfalse-fold_left.c: New test.
* gcc.target/aarch64/sve/pfalse-load.c: New test.
* gcc.target/aarch64/sve/pfalse-load_ext.c: New test.
* gcc.target/aarch64/sve/pfalse-load_ext_gather_index.c: New test.
* gcc.target/aarch64/sve/pfalse-load_ext_gather_offset.c: New test.
* gcc.target/aarch64/sve/pfalse-load_gather_sv.c: New test.
* gcc.target/aarch64/sve/pfalse-load_gather_vs.c: New test.
* gcc.target/aarch64/sve/pfalse-load_replicate.c: New test.
* gcc.target/aarch64/sve/pfalse-prefetch.c: New test.
* gcc.target/aarch64/sve/pfalse-prefetch_gather_index.c: New test.
* gcc.target/aarch64/sve/pfalse-prefetch_gather_offset.c: New test.
* gcc.target/aarch64/sve/pfalse-ptest.c: New test.
* gcc.target/aarch64/sve/pfalse-rdffr.c: New test.
* gcc.target/aarch64/sve/pfalse-reduction.c: New test.
* gcc.target/aarch64/sve/pfalse-reduction_wide.c: New test.
* gcc.target/aarch64/sve/pfalse-shift_right_imm.c: New test.
* gcc.target/aarch64/sve/pfalse-store.c: New test.
* gcc.target/aarch64/sve/pfalse-store_scatter_index.c: New test.
* gcc.target/aarch64/sve/pfalse-store_scatter_offset.c: New test.
* gcc.target/aarch64/sve/pfalse-storexn.c: New test.
* gcc.target/aarch64/sve/pfalse-ternary_opt_n.c: New test.
* gcc.target/aarch64/sve/pfalse-ternary_rotate.c: New test.
* gcc.target/aarch64/sve/pfalse-unary.c: New test.
* gcc.target/aarch64/sve/pfalse-unary_convert_narrowt.c: New test.
* gcc.target/aarch64/sve/pfalse-unary_convertxn.c: New test.
* gcc.target/aarch64/sve/pfalse-unary_n.c: New test.
* gcc.target/aarch64/sve/pfalse-unary_pred.c: New test.
* gcc.target/aarch64/sve/pfalse-unary_to_uint.c: New test.
* gcc.target/aarch64/sve/pfalse-unaryxn.c: New test.
* gcc.target/aarch64/sve2/pfalse-binary.c: New test.
* gcc.target/aarch64/sve2/pfalse-binary_int_opt_n.c: New test.
* gcc.target/aarch64/sve2/pfalse-binary_int_opt_single_n.c: New test.
* gcc.target/aarch64/sve2/pfalse-binary_opt_n.c: New test.
* gcc.target/aarch64/sve2/pfalse-binary_opt_single_n.c: New test.
* gcc.target/aarch64/sve2/pfalse-binary_to_uint.c: New test.
* gcc.target/aarch64/sve2/pfalse-binary_uint_opt_n.c: New test.
* gcc.target/aarch64/sve2/pfalse-binary_wide.c: New test.
* gcc.target/aarch64/sve2/pfalse-compare.c: New test.
* gcc.target/aarch64/sve2/pfalse-load_ext_gather_index_restricted.c:
New test.
* gcc.target/aarch64/sve2/pfalse-load_ext_gather_offset_restricted.c:
New test.
* gcc.target/aarch64/sve2/pfalse-load_gather_sv_restricted.c: New test.
* gcc.target/aarch64/sve2/pfalse-load_gather_vs.c: New test.
* gcc.target/aarch64/sve2/pfalse-shift_left_imm_to_uint.c: New test.
* gcc.target/aarch64/sve2/pfalse-shift_right_imm.c: New test.
* gcc.target/aarch64/sve2/pfalse-store_scatter_index_restricted.c:
New test.
* gcc.target/aarch64/sve2/pfalse-store_scatter_offset_restricted.c:
New test.
* gcc.target/aarch64/sve2/pfalse-unary.c: New test.
* gcc.target/aarch64/sve2/pfalse-unary_convert.c: New test.
* gcc.target/aarch64/sve2/pfalse-unary_convert_narrowt.c: New test.
* gcc.target/aarch64/sve2/pfalse-unary_to_int.c: New test.
Marek Polacek [Wed, 4 Dec 2024 21:58:59 +0000 (16:58 -0500)]
c++: ICE with pack indexing empty pack [PR117898]
Here we ICE with a partially-substituted pack indexing. The pack
expanded to an empty pack, which we can't index. It seems reasonable
to detect this case in tsubst_pack_index, even before we substitute
the index. Other erroneous cases can wait until pack_index_element
where we have the index.
PR c++/117898
gcc/cp/ChangeLog:
* pt.cc (tsubst_pack_index): Detect indexing an empty pack.
gcc/testsuite/ChangeLog:
* g++.dg/cpp26/pack-indexing2.C: Adjust.
* g++.dg/cpp26/pack-indexing12.C: New test.
Pan Li [Wed, 4 Dec 2024 02:08:12 +0000 (10:08 +0800)]
RISC-V: Refactor the testcases for bswap16-0
This patch would like to refactor the testcases of bswap16-0
after sorts of optimization option passing to testcase. To
fits the big lmul like m8 for asm dump check.
The below test suites are passed for this patch.
* The rv64gcv fully regression test.
It is test only patch and obvious up to a point, will commit it
directly if no comments in next 48H.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/unop/bswap16-0.c: Update
the vector register RE to cover v10 - v31.
Pan Li [Wed, 4 Dec 2024 02:08:11 +0000 (10:08 +0800)]
RISC-V: Fix incorrect optimization options passing to convert and unop
Like the strided load/store, the testcases of vector convert and unop
are designed to pick up different sorts of optimization options but
actually these option are ignored according to the Execution log of
the gcc.log.
This patch would like to make it correct almost the same as how we
fixed for strided load/store.
The below test suites are passed for this patch.
* The rv64gcv fully regression test.
It is test only patch and obvious up to a point, will commit it
directly if no comments in next 48H.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/rvv.exp: Fix the incorrect optimization
options passing to testcases.
Uros Bizjak [Thu, 5 Dec 2024 16:02:46 +0000 (17:02 +0100)]
i386: Fix addcarry/subborrow issues [PR117860]
Fix several things to enable combine to handle addcarry/subborrow patterns:
- Fix wrong canonical form of addcarry<mode> insn and friends. For
commutative operand (PLUS RTX) binary operand (LTU) takes precedence before
unary operand (ZERO_EXTEND).
- Swap operands of GTU comparison to canonicalize addcarry/subborrow
comparison. Again, the canonical form of the compare is PLUS RTX before
ZERO_EXTEND RTX. GTU comparison is not a carry flag comparison, so we have
to swap operands in x86_canonicalize_comparison to a non-canonical form
to use LTU comparison.
- Return correct compare mode (CCCmode) for addcarry/subborrow pattern
from ix86_cc_mode, so combine is able to emit required compare mode for
combined insn.
- Add *subborrow<mode>_1 pattern having const_scalar_int_operand predicate.
Here, canonicalization of SUB (op1, const) RTX to PLUS (op1, -const) requires
negation of constant operand when ckecking operands.
With the above changes, combine is able to create *addcarry_1/*subborrow_1
pattern with immediate operand for the testcase in the PR:
* config/i386/i386.cc (ix86_canonicalize_comparison): Swap
operands of GTU comparison to canonicalize addcarry/subborrow
comparison.
(ix86_cc_mode): Return CCCmode for the comparison of
addcarry/subborrow pattern.
* config/i386/i386.md (addcarry<mode>): Swap operands of
PLUS RTX to make it canonical.
(*addcarry<mode>_1): Ditto.
(addcarry peephole2s): Update RTXes for addcarry<mode>_1 change.
(*add<dwi>3_doubleword_cc_overflow_1): Ditto.
(*subborrow<mode>_1): New insn pattern.
The mmintrin.h header was adjusted for GCC-14 to generate a
(suppressible) warning if it was used, saying that support would be
removed in GCC-15.
Make that come true by removing the contents of this header and
emitting an error.
At this point in time I've not removed the internal support for the
intrinsics, just the wrappers that enable access to them. That can be
done at leisure from now on.
gcc/ChangeLog:
* config/arm/mmintrin.h: Raise an error if this header is used.
Remove other content.
This patch fixes the vluti* definitions to say that they don't
raise FP exceptions even for floating-point modes.
gcc/
* config/aarch64/aarch64-simd-pragma-builtins.def
(ENTRY_TERNARY_VLUT8): Use FLAG_QUIET rather than FLAG_DEFAULT.
(ENTRY_TERNARY_VLUT16): Likewise.
The flag now known as FLAG_QUIET is an odd-one-out in that it
removes side-effects rather than adding them. This patch inverts
it and gives it the old name FLAG_AUTO_FP. FLAG_QUIET now means
"no flags" instead.
gcc/
* config/aarch64/aarch64-builtins.cc (FLAG_QUIET): Redefine to 0,
replacing the old flag with...
(FLAG_AUTO_FP): ...this.
(FLAG_DEFAULT): Redefine to FLAG_AUTO_FP.
(aarch64_call_properties): Update accordingly.
This patch renames to FLAG_NONE to FLAG_DEFAULT. "NONE" suggests
that the function has no side-effects, whereas it actually means
that floating-point operations are assumed to read FPCR and to
raise FP exceptions.
gcc/
* config/aarch64/aarch64-builtins.cc (FLAG_NONE): Rename to...
(FLAG_DEFAULT): ...this and update all references.
* config/aarch64/aarch64-simd-builtins.def: Update all references
here too.
* config/aarch64/aarch64-simd-pragma-builtins.def: Likewise.
I'd suggested the name "FLAG_AUTO_FP" to mean "automatically derive
FLAG_FP from the mode", i.e. automatically decide whether the function
might read the FPCR or might raise FP exceptions. However, the flag
currently suppresses that behaviour instead.
This patch renames FLAG_AUTO_FP to FLAG_QUIET. That's probably not a
great name, but it's also what the SVE code means by "quiet", and is
borrowed from "quiet NaNs".
gcc/
* config/aarch64/aarch64-builtins.cc (FLAG_AUTO_FP): Rename to...
(FLAG_QUIET): ...this and update all references.
* config/aarch64/aarch64-simd-builtins.def: Update all references
here too.
Pan Li [Thu, 5 Dec 2024 01:19:39 +0000 (09:19 +0800)]
Match: Refactor the unsigned SAT_TRUNC match patterns [NFC]
This patch would like to refactor the all unsigned SAT_TRUNC patterns,
aka:
* Extract type check outside.
* Re-arrange the related match pattern forms together.
The below test suites are passed for this patch.
* The rv64gcv fully regression test.
* The x86 bootstrap test.
* The x86 fully regression test.
gcc/ChangeLog:
* match.pd: Refactor sorts of unsigned SAT_TRUNC match patterns.
Richard Biener [Wed, 27 Nov 2024 12:36:19 +0000 (13:36 +0100)]
middle-end/117801 - failed register coalescing due to GIMPLE schedule
For a TSVC testcase we see failed register coalescing due to a
different schedule of GIMPLE .FMA and stores fed by it. This
can be mitigated by making direct internal functions participate
in TER - given we're using more and more of such functions to
expose target capabilities it seems to be a natural thing to not
exempt those.
Unfortunately the internal function expanding API doesn't match
what we usually have - passing in a target and returning an RTX
but instead the LHS of the call is expanded and written to. This
makes the TER expansion of a call SSA def a bit unwieldly.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
The ccmp changes have likely not seen any coverage, the debug stmt
changes might not be optimal, we might end up losing on replaceable
calls.
PR middle-end/117801
* tree-outof-ssa.cc (ssa_is_replaceable_p): Make
direct internal function calls replaceable.
* expr.cc (get_def_for_expr): Handle replacements with calls.
(get_def_for_expr_class): Likewise.
(optimize_bitfield_assignment_op): Likewise.
(expand_expr_real_1): Likewise. Properly expand direct
internal function defs.
* cfgexpand.cc (expand_call_stmt): Handle replacements with calls.
(avoid_deep_ter_for_debug): Likewise, always create a debug temp
for calls.
(expand_debug_expr): Likewise, give up for calls.
(expand_gimple_basic_block): Likewise.
* ccmp.cc (ccmp_candidate_p): Likewise.
(get_compare_parts): Likewise.
Jonathan Wakely [Thu, 5 Dec 2024 12:46:26 +0000 (12:46 +0000)]
libstdc++: Use ADL swap for containers' function objects [PR117921]
The standard says that Compare, Pred and Hash objects should be swapped
as described in [swappable.requirements] which means calling swap
unqualified with std::swap visible to name lookup.
libstdc++-v3/ChangeLog:
PR libstdc++/117921
* include/bits/hashtable_policy.h (_Hash_code_base::_M_swap):
Use ADL swap for Hash members.
(_Hashtable_base::_M_swap): Use ADL swap for _Equal members.
* include/bits/stl_tree.h (_Rb_tree::swap): Use ADL swap for
_Compare members.
* testsuite/23_containers/set/modifiers/swap/adl.cc: New test.
* testsuite/23_containers/unordered_set/modifiers/swap-2.cc: New
test.
Jakub Jelinek [Thu, 5 Dec 2024 12:01:21 +0000 (13:01 +0100)]
doloop: Fix up doloop df use [PR116799]
The following testcases are miscompiled on s390x-linux, because the
doloop_optimize
/* Ensure that the new sequence doesn't clobber a register that
is live at the end of the block. */
{
bitmap modified = BITMAP_ALLOC (NULL);
for (rtx_insn *i = doloop_seq; i != NULL; i = NEXT_INSN (i))
note_stores (i, record_reg_sets, modified);
basic_block loop_end = desc->out_edge->src;
bool fail = bitmap_intersect_p (df_get_live_out (loop_end), modified);
check doesn't work as intended.
The problem is that it uses df, but the df analysis was only done using
iv_analysis_loop_init (loop);
->
df_analyze_loop (loop);
which computes df inside on the bbs of the loop.
While loop_end bb is inside of the loop, df_get_live_out computed that
way includes registers set in the loop and used at the start of the next
iteration, but doesn't include registers set in the loop (or before the
loop) and used after the loop.
The following patch fixes that by doing whole function df_analyze first,
changes the loop iteration mode from 0 to LI_ONLY_INNERMOST (on many
targets which use can_use_doloop_if_innermost target hook a so are known
to only handle innermost loops) or LI_FROM_INNERMOST (I think only bfin
actually allows non-innermost loops) and checking not just
df_get_live_out (loop_end) (that is needed for something used by the
next iteration), but also df_get_live_in (desc->out_edge->dest),
i.e. what will be used after the loop. df of such a bb shouldn't
be affected by the df_analyze_loop and so should be from df_analyze
of the whole function.
2024-12-05 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/113994
PR rtl-optimization/116799
* loop-doloop.cc: Include targhooks.h.
(doloop_optimize): Also punt on intersection of modified
with df_get_live_in (desc->out_edge->dest).
(doloop_optimize_loops): Call df_analyze. Use
LI_ONLY_INNERMOST or LI_FROM_INNERMOST instead of 0 as
second loops_list argument.
* gcc.c-torture/execute/pr116799.c: New test.
* g++.dg/torture/pr113994.C: New test.
Jakub Jelinek [Thu, 5 Dec 2024 11:57:44 +0000 (12:57 +0100)]
c: Diagnose unexpected va_start arguments in C23 [PR107980]
va_start macro was changed in C23 from the C17 va_start (va_list ap, parmN)
where parmN is the identifier of the last parameter into
va_start (va_list ap, ...) where arguments after ap aren't evaluated.
Late in the C23 development
"If any additional arguments expand to include unbalanced parentheses, or
a preprocessing token that does not convert to a token, the behavior is
undefined."
has been added, plus there is
"NOTE The macro allows additional arguments to be passed for va_start for
compatibility with older versions of the library only."
and
"Additional arguments beyond the first given to the va_start macro may be
expanded and used in unspecified contexts where they are unevaluated. For
example, an implementation diagnoses potentially erroneous input for an
invocation of va_start such as:"
...
va_start(vl, 1, 3.0, "12", xd); // diagnostic encouraged
...
"Simultaneously, va_start usage consistent with older revisions of this
document should not produce a diagnostic:"
...
void neigh (int last_arg, ...) {
va_list vl;
va_start(vl, last_arg); // no diagnostic
The following patch implements the recommended diagnostics.
Until now in C23 mode va_start(v, ...) was defined to
__builtin_va_start(v, 0)
and the extra arguments were silently ignored.
The following patch adds a new builtin in a form of a keyword which
parses the first argument, is silent about the __builtin_c23_va_start (ap)
form, for __builtin_c23_va_start (ap, identifier) looks the identifier up
and is silent if it is the last named parameter (except that it diagnoses
if it has register keyword), otherwise diagnoses it isn't the last one
but something else, and if there is just __builtin_c23_va_start (ap, )
or if __builtin_c23_va_start (ap, is followed by tokens other than
identifier followed by ), it skips over the tokens (with handling of
balanced ()s) until ) and diagnoses the extra tokens.
In all cases in a form of warnings.
2024-12-05 Jakub Jelinek <jakub@redhat.com>
PR c/107980
gcc/
* ginclude/stdarg.h (va_start): For C23+ change parameters from
v, ... to just ... and define to __builtin_c23_va_start(__VA_ARGS__)
rather than __builtin_va_start(v, 0).
gcc/c-family/
* c-common.h (enum rid): Add RID_C23_VA_START.
* c-common.cc (c_common_reswords): Add __builtin_c23_va_start.
gcc/c/
* c-parser.cc (c_parser_postfix_expression): Handle RID_C23_VA_START.
gcc/testsuite/
* gcc.dg/c23-stdarg-4.c: Expect extra warning.
* gcc.dg/c23-stdarg-6.c: Likewise.
* gcc.dg/c23-stdarg-7.c: Likewise.
* gcc.dg/c23-stdarg-8.c: Likewise.
* gcc.dg/c23-stdarg-10.c: New test.
* gcc.dg/c23-stdarg-11.c: New test.
* gcc.dg/torture/c23-stdarg-split-1a.c: Expect extra warning.
* gcc.dg/torture/c23-stdarg-split-1b.c: Likewise.
gcc/
PR target/107957
* config/avr/avr-passes-fuse-move.h (bbinfo_t) <try_mem0_p>:
Add static property.
* config/avr/avr-passes.cc (bbinfo_t::try_mem0_p): Define it.
(optimize_data_t::try_mem0): New method.
(bbinfo_t::optimize_one_block) [bbinfo_t::try_mem0_p]: Run try_mem0.
(bbinfo_t::optimize_one_function): Set bbinfo_t::try_mem0_p.
* config/avr/avr.md (pushhi1_insn): Also allow zero as source.
(define_split) [avropt_split_ldst]: Only run avr_split_ldst()
when avr-fuse-move has been run at least once.
* doc/invoke.texi (AVR Options) <-msplit-ldst>: Document it.
AVR: target/107957 - Split multi-byte loads and stores.
This patch splits multi-byte loads and stores into single-byte
ones provided:
- New option -msplit-ldst is on (e.g. -O2 and higher), and
- The memory is non-volatile, and
- The address space is generic, and
- The split addresses are natively supported by the hardware.
gcc/
PR target/107957
* config/avr/avr.opt (-msplit-ldst, avropt_split_ldst):
New option and associated var.
* common/config/avr/avr-common.cc (avr_option_optimization_table)
[OPT_LEVELS_2_PLUS]: Turn on -msplit_ldst.
* config/avr/avr-passes.cc (splittable_address_p)
(avr_byte_maybe_mem, avr_split_ldst): New functions.
* config/avr/avr-protos.h (avr_split_ldst): New proto.
* config/avr/avr.md (define_split) [avropt_split_ldst]: Run
avr_split_ldst().
AVR: target/64242 - Copy FP to a local reg in nonlocal_goto.
In nonlocal_goto sets, change hard_frame_pointer_rtx only after
emit_stack_restore() restored SP. This is needed because SP
my be stored in some frame location.
gcc/
PR target/64242
* config/avr/avr.md (nonlocal_goto): Don't restore
hard_frame_pointer_rtx directly, but copy it to local
register, and only set hard_frame_pointer_rtx from it
after emit_stack_restore().
AVR: Rework patterns that add / subtract an (inverted) MSB.
gcc/
* config/avr/avr-protos.h (avr_out_add_msb): New proto.
* config/avr/avr.cc (avr_out_add_msb): New function.
(avr_adjust_insn_length) [ADJUST_LEN_ADD_GE0,
ADJUST_LEN_ADD_LT0]: Handle cases.
* config/avr/avr.md (adjust_len) <add_lt0, add_ge0>: New attr values.
(QISI2): New mode iterator.
(C_MSB): New mode_attr.
(*add<mode>3...msb_split, *add<mode>3.ge0, *add<mode>3.lt0)
(*sub<mode>3...msb_split, *sub<mode>3.ge0, *sub<mode>3.lt0): New
patterns replacing old ones, but with iterators and
using avr_out_add_msb() for asm out.
Jakub Jelinek [Thu, 5 Dec 2024 08:25:06 +0000 (09:25 +0100)]
Allow limited extended asm at toplevel [PR41045]
In the Cauldron IPA/LTO BoF we've discussed toplevel asms and it was
discussed it would be nice to tell the compiler something about what
the toplevel asm does. Sure, I'm aware the kernel people said they
aren't willing to use something like that, but perhaps other projects
do. And for kernel perhaps we should add some new option which allows
some dumb parsing of the toplevel asms and gather something from that
parsing.
The following patch is just a small step towards that, namely, allow
some subset of extended inline asm outside of functions.
The patch is unfinished, LTO streaming (out/in) of the ASM_EXPRs isn't
implemented (it emits a sorry diagnostics), nor any cgraph/varpool
changes to find out references etc.
The patch allows something like:
int a[2], b;
enum { E1, E2, E3, E4, E5 };
struct S { int a; char b; long long c; };
asm (".section blah; .quad %P0, %P1, %P2, %P3, %P4; .previous"
: : "m" (a), "m" (b), "i" (42), "i" (E4), "i" (sizeof (struct S)));
Even for non-LTO, that could be useful e.g. for getting enumerators from
C/C++ as integers into the toplevel asm, or sizeof/offsetof etc.
The restrictions I've implemented are:
1) asm qualifiers aren't still allowed, so asm goto or asm inline can't be
specified at toplevel, asm volatile has the volatile ignored for C++ with
a warning and is an error in C like before
2) I see good use for mainly input operands, output maybe to make it clear
that the inline asm may write some memory, I don't see a good use for
clobbers, so the patch doesn't allow those (and of course labels because
asm goto can't be specified)
3) the patch allows only constraints which don't allow registers, so
typically "m" or "i" or other memory or immediate constraints; for
memory, it requires that the operand is addressable and its address
could be used in static var initializer (so that no code actually
needs to be emitted for it), for others that they are constants usable
in the static var initializers
4) the patch disallows + (there is no reload of the operands, so I don't
see benefits of tying some operands together), nor % (who cares if
something is commutative in this case), or & (again, no code is emitted
around the asm), nor the 0-9 constraints
Right now there is no way to tell the compiler that the inline asm defines
some symbol, that is implemented in a later patch, as : constraint.
Similarly, the c modifier doesn't work in all cases and the cc modifier
is implemented separately.
2024-12-05 Jakub Jelinek <jakub@redhat.com>
PR c/41045
gcc/
* output.h (insn_noperands): Declare.
* final.cc (insn_noperands): No longer static.
* varasm.cc (assemble_asm): Handle ASM_EXPR.
* lto-streamer-out.cc (lto_output_toplevel_asms): Add sorry_at
for non-STRING_CST toplevel asm for now.
* doc/extend.texi (Basic @code{asm}, Extended @code{asm}): Document
that extended asm is now allowed outside of functions with certain
restrictions.
gcc/c/
* c-parser.cc (c_parser_asm_string_literal): Add forward declaration.
(c_parser_asm_definition): Parse also extended asm without
clobbers/labels.
* c-typeck.cc (build_asm_expr): Allow extended asm outside of
functions and check extra restrictions.
gcc/cp/
* cp-tree.h (finish_asm_stmt): Add TOPLEV_P argument.
* parser.cc (cp_parser_asm_definition): Parse also extended asm
without clobbers/labels outside of functions.
* semantics.cc (finish_asm_stmt): Add TOPLEV_P argument, if set,
check extra restrictions for extended asm outside of functions.
* pt.cc (tsubst_stmt): Adjust finish_asm_stmt caller.
gcc/testsuite/
* c-c++-common/toplevel-asm-1.c: New test.
* c-c++-common/toplevel-asm-2.c: New test.
* c-c++-common/toplevel-asm-3.c: New test.
We were not consistently traversing method declarations, which appear
if there is a method without a body. The gc compiler rejects that
case, but gofrontend currently permits it. Maybe that should change,
but not today.
This avoids a compiler crash if there are method declarations
with types that require specific functions. I didn't bother
with a test case because a program with method declarations is
almost certainly invalid anyhow.
David Malcolm [Wed, 4 Dec 2024 22:34:27 +0000 (17:34 -0500)]
c++: give suggestion on misspelled class name [PR116771]
gcc/cp/ChangeLog:
PR c++/116771
* parser.cc (cp_parser_name_lookup_error): Provide suggestions for
the case of complete failure where there is no scope.
gcc/testsuite/ChangeLog:
PR c++/116771
* g++.dg/spellcheck-pr116771.C: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
sched1 computes ECC (Excess Change Cost) for each insn, which represents
the register pressure attributed to the insn.
Currently the pressure sensitive scheduling algorithm deliberately ignores
negative ECC values (pressure reduction), making them 0 (neutral), leading
to more spills. This happens due to the assumption that the compiler has
a reasonably accurate processor pipeline scheduling model and thus tries
to aggresively fill pipeline bubbles with spill slots.
This however might not be true, as the model might not be available for
certains uarches or even applicable especially for modern out-of-order cores.
The existing heuristic induces spill frenzy on RISC-V, noticably so on
SPEC2017 507.Cactu. If insn scheduling is disabled completely, the
total dynamic icounts for this workload are reduced in half from
~2.5 trillion insns to ~1.3 (w/ -fno-schedule-insns).
This patch adds --param=cycle-accurate-model={0,1} to gate the spill
behavior.
- The default (1) preserves existing spill behavior.
- targets/uarches sensitive to spilling can override the param to (0)
to get the reverse effect. RISC-V backend does so too.
The actual perf numbers are very promising.
(1) On RISC-V BPI-F3 in-order CPU, -Ofast -march=rv64gcv_zba_zbb_zbs:
Before:
------
Performance counter stats for './cactusBSSN_r_base.rivos spec_ref.par':
gcc/ChangeLog:
PR target/11472
* params.opt (--param=cycle-accurate-model=): New opt.
* doc/invoke.texi (cycle-accurate-model): Document.
* haifa-sched.cc (model_excess_group_cost): Return negative
delta if param_cycle_accurate_model is 0.
(model_excess_cost): Ceil negative baseECC to 0 only if
param_cycle_accurate_model is 1.
Dump the actual ECC value.
* config/riscv/riscv.cc (riscv_option_override): Set param
to 0.
gcc/testsuite/ChangeLog:
PR target/114729
* gcc.target/riscv/riscv.exp: Enable new tests to build.
* gcc.target/riscv/sched1-spills/spill1.cpp: Add new test.
Filip Kastl [Wed, 4 Dec 2024 14:46:54 +0000 (15:46 +0100)]
contrib: Fix 2 bugs in check-params-in-docs.py
In my last patch for check-params-in-docs.py I accidentally
1. left one occurence of the 'help_params' variable not renamed
2. converted 'help_params' from a dict to a list
These issues cause the script to error when encountering a parameter
missing in docs. This patch should fix these issues.
contrib/ChangeLog:
* check-params-in-docs.py: 'params' -> 'help_params'. Don't
convert 'help_params' to a list.
David Malcolm [Wed, 4 Dec 2024 13:40:34 +0000 (08:40 -0500)]
arm: use quotes when referring to command-line options [PR90160]
gcc/ChangeLog:
PR translation/90160
* config/arm/arm.cc (arm_option_check_internal): Use quotes in
messages that refer to command-line options. Tweak wording.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Simon Martin [Tue, 3 Dec 2024 13:30:43 +0000 (14:30 +0100)]
c++: Don't reject pointer to virtual method during constant evaluation [PR117615]
We currently reject the following valid code:
=== cut here ===
struct Base {
virtual void doit (int v) const {}
};
struct Derived : Base {
void doit (int v) const {}
};
using fn_t = void (Base::*)(int) const;
struct Helper {
fn_t mFn;
constexpr Helper (auto && fn) : mFn(static_cast<fn_t>(fn)) {}
};
void foo () {
constexpr Helper h (&Derived::doit);
}
=== cut here ===
The problem is that since r6-4014-gdcdbc004d531b4, &Derived::doit is
represented with an expression with type pointer to method and using an
INTEGER_CST (here 1), and that cxx_eval_constant_expression rejects any
such expression with a non-null INTEGER_CST.
This patch uses the same strategy as r12-4491-gf45610a45236e9 (fix for
PR c++/102786), and simply lets such expressions go through.
PR c++/117615
gcc/cp/ChangeLog:
* constexpr.cc (cxx_eval_constant_expression): Don't reject
INTEGER_CSTs with type POINTER_TYPE to METHOD_TYPE.
Jakub Jelinek [Wed, 4 Dec 2024 09:54:41 +0000 (10:54 +0100)]
c++: Fix up erroneous template error recovery ICE [PR117826]
The testcase in the PR (which can't be easily reduced and is
way too large and has way too many errors) results in an ICE,
because the erroneous_templates hash_map holds trees of erroneous
templates across ggc_collect and some of the templates in there
could be removed, so the later lookup can crash on comparison of
already freed and reused trees.
The following patch makes the hash_map GTY((cache)) marked.
The cp-tree.h changes before the erroneous_template declaration
are needed to make gengtype happy, it didn't like using
directive nor using a template-id as a template parameter.
It is marked cache because if a decl would be solely referenced from
the erroneous_templates hash_map, then nothing would look it up.
2024-12-04 Jakub Jelinek <jakub@redhat.com>
PR c++/117826
* cp-tree.h (struct decl_location_traits): New type.
(erroneous_templates_t): Change using into typedef.
(erroneous_templates): Add GTY((cache)).
* error.cc (cp_adjust_diagnostic_info): Use
hash_map_safe_get_or_insert<true> rather than
hash_map_safe_get_or_insert<false> for erroneous_templates.
Richard Biener [Tue, 3 Dec 2024 13:37:21 +0000 (14:37 +0100)]
tree-optimization/116083 - SLP discovery slowness
One large constant factor of SLP discovery is figuring the vector
type for each individual lane of each node. That should be redundant
since the structual comparison of stmts should ensure they end up
the same so the following computes them only once per node rather
than for each lane.
This cuts the compile-time of the testcase in half.
PR tree-optimization/116083
* tree-vect-slp.cc (vect_build_slp_tree_1): Compute vector
type and max_nunits only once. Remove check for matching
vector type of each lane and replace it with matching check
for LHS type.
Pan Li [Wed, 4 Dec 2024 05:53:52 +0000 (13:53 +0800)]
RISC-V: Add assert for insn operand out of range access [PR117878][NFC]
According to the the initial analysis of PR117878, the ice comes from
the out-of-range operand access for recog_data.operand[]. Thus, add
one assert here to expose this explicitly.
PR target/117878
gcc/ChangeLog:
* config/riscv/riscv-v.cc (vlmax_avl_type_p): Add assert for
out of range access.
(nonvlmax_avl_type_p): Ditto.
Andrew Pinski [Mon, 2 Dec 2024 16:35:23 +0000 (08:35 -0800)]
phiopt: Reset the number of iterations information of a loop when changing an exit from the loop [PR117243]
After r12-5300-gf98f373dd822b3, phiopt could get the following bb structure:
|
middle-bb -----|
| |
| |----| |
phi<1, 2> | |
cond | |
| | |
|--------+---|
Which was considered 2 loops. The inner loop had esimtate of upper_bound to be 8,
due to the original `for (b = 0; b <= 7; b++)`. The outer loop was already an
infinite one.
So phiopt would come along and change the condition to be unconditionally true,
we change the inner loop to being an infinite one but don't reset the estimate
on the loop and cleanup cfg comes along and changes it into one loop but also
does not reset the estimate of the loop. Then the loop unrolling uses the old estimate
and decides to add an unreachable there.o
So the fix is when phiopt changes an exit to a loop, reset the estimates, similar to
how cleanupcfg does it when merging some basic blocks.
The standard says that std::exclusive_scan can be used to work in
place, i.e. where the output range is the same as the input range. This
means that the first sum cannot be written to the output until after
reading the first input value, otherwise we'll already have overwritten
the first input value.
While writing a new testcase I also realised that the serial version of
std::exclusive_scan uses copy construction for the accumulator variable,
but the standard only requires Cpp17MoveConstructible. We also require
move assignable, which is missing from the standard's requirements, but
we should at least use move construction not copy construction.
A similar problem exists for some other new C++17 numeric algos, but
I'll fix the others in a subsequent commit.
libstdc++-v3/ChangeLog:
PR libstdc++/108236
* include/pstl/glue_numeric_impl.h (exclusive_scan): Pass __init
as rvalue.
* include/pstl/numeric_impl.h (__brick_transform_scan): Do not
write through __result until after reading through __first. Move
__init into return value.
(__pattern_transform_scan): Pass __init as rvalue.
* include/std/numeric (exclusive_scan): Move construct instead
of copy constructing.
* testsuite/26_numerics/exclusive_scan/2.cc: New test.
* testsuite/26_numerics/pstl/numeric_ops/108236.cc: New test.
Jonathan Wakely [Mon, 25 Nov 2024 21:55:09 +0000 (21:55 +0000)]
libstdc++: Simplify allocator propagation helpers using 'if constexpr'
Use diagnostic pragmas to allow using `if constexpr` in C++11 mode, so
that we don't need to use tag dispatching.
These helpers could be removed entirely by just using `if constexpr`
directly in the container member functions, but that's a slightly larger
change that can happen later.
It also looks like we could remove the __alloc_on_copy(const Alloc&)
overload, which is unused.
libstdc++-v3/ChangeLog:
* include/bits/alloc_traits.h (__do_alloc_on_copy): Remove.
(__do_alloc_on_move __do_alloc_on_swap): Remove.
(__alloc_on_copy, __alloc_on_move, __alloc_on_swap): Use if
constexpr.
Jonathan Wakely [Fri, 15 Nov 2024 21:45:16 +0000 (21:45 +0000)]
libstdc++: Add fancy pointer support to std::forward_list [PR57272]
This takes a very similar approach to the changes for std::list.
libstdc++-v3/ChangeLog:
PR libstdc++/57272
* include/bits/forward_list.h (_GLIBCXX_USE_ALLOC_PTR_FOR_LIST):
Define.
(_Fwd_list_node_base::_M_base_ptr): New member functions.
(_Fwd_list_node::_M_node_ptr): New member function.
(_Fwd_list_iterator, _Fwd_list_const_iterator): Make internal
member functions and data member private. Declare forward_list
and _Fwd_list_base as friends.
(__fwdlist::_Node_base, __fwdlist::_Node, __fwdlist::_Iterator):
New class templates.
(__fwdlist::_Node_traits): New class template.
(_Fwd_list_base): Use _Node_traits to get types. Use _Base_ptr
instad of _Fwd_list_node_base*. Use _M_base_ptr() instead of
taking address of head node.
(forward_list): Likewise.
(_Fwd_list_base::_M_get_node): Do not define for versioned
namespace.
(_Fwd_list_base::_M_put_node): Only convert pointer if needed.
(_Fwd_list_base::_M_create_node): Use __allocate_guarded_obj.
(_Fwd_list_base::_M_destroy_node): New member function.
* include/bits/forward_list.tcc (_Fwd_list_base::_M_insert_after)
(forward_list::_M_splice_after, forward_list::insert_after): Use
const_iterator::_M_const_cast() instead of casting pointers.
(_Fwd_list_base::_M_erase_after): Use _M_destroy_node.
(forward_list::remove, forward_list::remove_if): Only do
downcasts when accessing the value.
(forward_list::sort): Likewise.
* testsuite/23_containers/forward_list/capacity/1.cc: Check
max_size for new node type.
* testsuite/23_containers/forward_list/capacity/node_sizes.cc:
New test.
* testsuite/23_containers/forward_list/requirements/explicit_instantiation/alloc_ptr.cc:
New test.
* testsuite/23_containers/forward_list/requirements/explicit_instantiation/alloc_ptr_ignored.cc:
New test.
Jonathan Wakely [Fri, 15 Nov 2024 19:06:47 +0000 (19:06 +0000)]
libstdc++: Add fancy pointer support to std::list [PR57272]
Currently std::list uses raw pointers to connect its nodes, which is
non-conforming. We should use the allocator's pointer type everywhere
that a "pointer" is needed.
Because the existing types like _List_node<T> are part of the ABI now,
we can't change them. To support nodes that are connected by fancy
pointers we need a parallel hierarchy of node types. This change
introduces new class templates parameterized on the allocator's
void_pointer type, __list::_Node_base and __list::_Node_header, and new
class templates parameterized on the allocator's pointer type,
__list::Node, __list::_Iterator. The iterator class template is used for
both iterator and const_iterator. Whether std::list<T, A> should use the
old _List_node<T> or new _list::_Node<A::pointer> type family internally
is controlled by a new __list::_Node_traits traits template.
Because std::pointer_traits and std::__to_address are not defined for
C++98, there is no way to support fancy pointers in C++98. For C++98 the
_Node_traits traits always choose the old _List_node family.
In case anybody is currently using std::list with an allocator that has
a fancy pointer, this change would be an ABI break, because their
std::list instantiations would start to (correctly) use the fancy
pointer type. If the fancy pointer just contains a single pointer and so
has the same size, layout, and object represenation as a raw pointer,
the code might still work (despite being an ODR violation). But if their
fancy pointer has a different representation, they would need to
recompile all their code using that allocator with std::list. Because
std::list will never use fancy pointers in C++98 mode, recompiling
everything to use fancy pointers isn't even possible if mixing C++98 and
C++11 code that uses std::list. To alleviate this problem, compiling
with -D_GLIBCXX_USE_ALLOC_PTR_FOR_LIST=0 will force std::list to have
the old, non-conforming behaviour and use raw pointers internally. For
testing purposes, compiling with -D_GLIBCXX_USE_ALLOC_PTR_FOR_LIST=9001
will force std::list to always use the new node types. This macro is
currently undocumented, which needs to be fixed.
The original _List_node<T> type is trivially constructible and trivially
destructible, but the new __list::_Node<Ptr> type might not be,
depending on the fancy pointer data members in _Node_base. This means
that std::list needs to explicitly construct and destroy the node
object, not just the value that it contains. This commit adds a new
__allocated_obj helper which wraps an __allocated_ptr and additionally
constructs and destroys an object in the allocated storage.
Pretty printers for std::list need to be updated to handle the new node
types. Potentially we just can't pretty print them, because we don't
know how to follow the fancy pointers to traverse the list.
libstdc++-v3/ChangeLog:
PR libstdc++/57272
PR libstdc++/110952
* include/bits/allocated_ptr.h (__allocated_ptr::get): Add
const.
(__allocated_ptr::operator bool, __allocated_ptr::release): New
member functions.
(__allocate_guarded): Add inline.
(__allocated_obj): New class template.
(__allocate_guarded_obj): New function template.
* include/bits/list.tcc (_List_base::_M_clear()): Replace uses
of raw pointers. Use _M_destroy_node.
(list::emplace, list::insert): Likewise.
(list::sort): Adjust check for 0 or 1 wsize. Use template
argument list for _Scratch_list.
* include/bits/stl_list.h (_GLIBCXX_USE_ALLOC_PTR_FOR_LIST):
Define.
(_List_node_base::_Base_ptr): New typedef.
(_List_node_base::_M_base): New member functions.
(_List_node_header::_M_base): Make public and add
using-declaration for base class overload.
(__list::_Node_traits, __list::_Node_base)
(__list::_Node_header, __list::_Node, __list::_Iterator): New
class templates.
(_Scratch_list): Turn class into class template. Use _Base_ptr
typedef instead of _List_node_base*.
(_List_node::_Node_ptr): New typedef.
(_List_node::_M_node_ptr): New member function.
(_List_base, _List_impl): Use _Node_traits to get node types.
(_List_base::_M_put_node): Convert to fancy pointer if needed.
(_List_base::_M_destroy_node): New member function.
(_List_base(_List_base&&, _Node_alloc_type&&)): Use if constexpr
to make function a no-op for fancy pointers.
(_List_base::_S_distance, _List_base::_M_distance)
(_List_base::_M_node_count): Likewise.
(list): Use _Node_traits to get iterator, node and pointer
types.
(list::_M_create_node): Use _Node_ptr typedef instead of _Node*.
Use __allocate_guarded_obj instead of _M_get_node.
(list::end, list::cend, list::empty): Use node header's
_M_base() function instead of taking its address.
(list::swap): Use _Node_traits to get node base type.
(list::_M_create_node, list::_M_insert): Use _Node_ptr instead
of _Node*.
(list::_M_erase): Likewise. Use _M_destroy_node.
(__distance): Overload for __list::_Iterator.
(_Node_base::swap, _Node_base::_M_transfer): Define non-inline
member functions of class templates.
(_Node_header::_M_reverse): Likewise.
* testsuite/23_containers/list/capacity/29134.cc: Check max_size
for allocator of new node type.
* testsuite/23_containers/list/capacity/node_sizes.cc: New test.
* testsuite/23_containers/list/requirements/explicit_instantiation/alloc_ptr.cc:
New test.
* testsuite/23_containers/list/requirements/explicit_instantiation/alloc_ptr_ignored.cc:
New test.
Jonathan Wakely [Tue, 12 Nov 2024 15:36:17 +0000 (15:36 +0000)]
libstdc++: Refactor std::list::size() for cxx11 ABI
Remove some preprocessor conditionals by moving the _M_size member for
the cxx11 ABI into a new base class, which is empty for the gcc4-compat
ABI.
Move some unused members that are only retained for ABI compatibility to
the end of _List_base and add an explanatory comment. Stop using
list::_M_node_count and list::_D_distance and then move them to the end
of std::list with a comment too.
libstdc++-v3/ChangeLog:
* include/bits/stl_list.h (_List_size): New struct.
(_List_node_header): Replace _M_size member with _List_size base
class.
(_List_node_header(_List_node_header&&)): Replace explicit uses
of _M_size with initializing the base.
(_List_node_header::_M_init): Likewise.
(_List_base::_S_distance, _List_base::_M_distance)
(_List_base::_M_node_count): Move to end of class body and add
comment.
(list::_S_distance, list::_M_node_count): Likewise.
(list::size): Inline _M_node_count effects to here.
(list::splice(iterator, list&, iterator, iterator)): Use #if and
call std::distance instead of _S_distance.
Some diagnostics are issues late, e.g. in avr_print_operand().
This patch uses the insn's location as a proxy for the operand
location. Without the patch, the location is usually input_location,
which points to the closing } of the function body.
gcc/
* config/avr/avr.cc (avr_insn_location): New variable.
(avr_final_prescan_insn): Set avr_insn_location.
(avr_asm_final_postscan_insn): Unset avr_insn_location after last insn.
(avr_print_operand): Pass avr_insn_location to warning_at.
Jeff Law [Tue, 3 Dec 2024 19:26:01 +0000 (12:26 -0700)]
Move some CRC tests into the gcc.dg/torture directory
Jakub noted that these tests were using dg-skip-if directives that implied the
tests were expected to run under multiple optimization options, which means
they probably should be in gcc.dg/torture rather than in the gcc.dg directory.
This moves the relevant tests from gcc.dg to gcc.dg/torture.
Nina Ranns [Tue, 3 Dec 2024 14:58:21 +0000 (14:58 +0000)]
c++/contracts: ICE with contract assert on non-empty statement [PR 117579]
Contract assert is an attribute on an empty statement. Currently we assert
that the statement is empty before emitting the assertion. This has been
changed to a conditional check that the statement is empty before the
assertion is emitted.
PR c++/117579
gcc/cp/ChangeLog:
* parser.cc (cp_parser_statement): Replace assertion with a
conditional check that the statement containing a contract assert
is empty.
gcc/testsuite/ChangeLog:
* g++.dg/contracts/pr117579.C: New test.
Signed-off-by: Nina Ranns <dinka.ranns@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
David Malcolm [Tue, 3 Dec 2024 18:53:46 +0000 (13:53 -0500)]
maintainer-scripts: build the libgdiagnostics docs for the website [PR117883]
maintainer-scripts/ChangeLog:
PR web/117883
* update_web_docs_git: Introduce SPHINX_VENV to make
it easier to test the script. Add the libgdiagnostics docs
and testsuite to the files to be preserved. Use sphinx to build
the libgdiagnostics docs as HTML. Copy them into $DOCSDIR.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
David Malcolm [Tue, 3 Dec 2024 18:53:42 +0000 (13:53 -0500)]
maintainer-scripts: fix jit docs on website
I noticed whilst working on the libgdiagnostics docs
that some errors like this were occurring in the jit docs:
/tmp/gcc-doc-update.3782849/gcc/gcc/jit/docs/cp/topics/asm.rst:63: WARNING: Include file '/tmp/gcc-doc-update.3782849/gcc/gcc/testsuite/jit.dg/test-asm.cc' not found or reading it failed
which was occurring for:
* test-asm.c and .cc
* test-switch.c
* test-accessing-union.c
and indeed https://gcc.gnu.org/onlinedocs/jit/topics/asm.html is
currently missing various code examples.
Fixed thusly; tested locally.
maintainer-scripts/ChangeLog:
* update_web_docs_git: Add the jit testsuite to the files to
be preserved, since this is used by the jit docs.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Edwin Lu [Tue, 3 Dec 2024 01:29:55 +0000 (17:29 -0800)]
RISC-V: Fix test target selector
The previous target selector was not properly gating the tests to rv32
and rv64 targets. This was triggering an excess failure on rv32 targets
where it would try to run the zbc64 tests. Fix selector
Paul Thomas [Tue, 3 Dec 2024 15:56:53 +0000 (15:56 +0000)]
Fortran: Fix class transformational intrinsic calls [PR102689]
2024-12-03 Paul Thomas <pault@gcc.gnu.org>
gcc/fortran
PR fortran/102689
* trans-array.cc (get_array_ref_dim_for_loop_dim): Use the arg1
class container carried in ss->info as the seed for a lhs in
class valued transformational intrinsic calls that are not the
rhs of an assignment. Otherwise, the lhs variable expression is
taken from the loop chain. For this latter case, the _vptr and
_len fields are set.
(gfc_trans_create_temp_array): Use either the lhs expression
seeds to build a class variable that will take the returned
descriptor as its _data field. In the case that the arg1 expr.
is used, 'atmp' must be marked as unused, a typespec built with
the correct rank and the _vptr and _len fields set. The element
size is provided for the temporary allocation and to set the
descriptor span.
(gfc_array_init_size): When an intrinsic type scalar expr3 is
used in allocation of a class array, use its element size in
the descriptor dtype.
* trans-expr.cc (gfc_conv_class_to_class): Class valued
transformational intrinsics return the pointer to the array
descriptor as the _data field of a class temporary. Extract
directly and return the address of the class temporary.
(gfc_conv_procedure_call): store the expression for the first
argument of a class valued transformational intrinsic function
in the ss info class_container field. Later, use its type as
the element type in the call to gfc_trans_create_temp_array.
(fcncall_realloc_result): Add a dtype argument and use it in
the descriptor, when available.
(gfc_trans_arrayfunc_assign): For class lhs, build a dtype with
the lhs rank and the rhs element size and use it in the call to
fcncall_realloc_result.
gcc/testsuite/
PR fortran/102689
* gfortran.dg/class_transformational_1.f90: New test for class-
valued reshape.
* gfortran.dg/class_transformational_2.f90: New test for other
class_valued transformational intrinsics.
Joseph Myers [Tue, 3 Dec 2024 13:01:58 +0000 (13:01 +0000)]
preprocessor: Adjust C rules on UCNs for C23 [PR117162]
As noted in bug 117162, C23 changed some rules on UCNs to match C++
(this was a late change agreed in the resolution to CD2 comment
US-032, implementing changes from N3124), which we need to implement.
Allow UCNs below 0xa0 outside identifiers for C, with a
pedwarn-if-pedantic before C23 (and a warning with -Wc11-c23-compat)
except for the always-allowed cases of UCNs for $ @ `. Also as part
of that change, do not allow \u0024 in identifiers as equivalent to $
for C23.
Bootstrapped with no regressions for x86_64-pc-linux-gnu.
PR c/117162
libcpp/
* include/cpplib.h (struct cpp_options): Add low_ucns.
* init.cc (struct lang_flags, lang_defaults): Add low_ucns.
(cpp_set_lang): Set low_ucns
* charset.cc (_cpp_valid_ucn): For C, allow UCNs below 0xa0
outside identifiers, with a pedwarn if pedantic before C23 or a
warning with -Wc11-c23-compat. Do not allow \u0024 in identifiers
for C23.
Richard Biener [Tue, 3 Dec 2024 07:56:35 +0000 (08:56 +0100)]
tree-optimization/117874 - optimize SLP discovery budget use
The following tries to avoid eating into the SLP discovery limit
when we can do cheaper checks first. Together with the previous
patch this allows to use two-lane SLP discovery for mult_su3_an
in 433.milc.
PR tree-optimization/117874
* tree-vect-slp.cc (vect_build_slp_tree_2): Perform early
reassoc checks before eating into discovery limit.
Richard Biener [Tue, 3 Dec 2024 07:52:48 +0000 (08:52 +0100)]
Use the number of relevant stmts to limit SLP build
The following removes scalar stmt counting from loop vectorization
and using that as base to limit both the SLP tree final size and
discovery. Instead use the number of relevant stmts for that
which is conveniently the number of stmt_vec_infos we create which
in turn includes things like pattern stmts.
PR tree-optimization/117874
* tree-vectorizer.h (vec_info_shared::n_stmts): Remove.
(LOOP_VINFO_N_STMTS): Likewise.
* tree-vectorizer.cc (vec_info_shared::vec_info_shared): Adjust.
* tree-vect-loop.cc (vect_get_datarefs_in_loop): Do not
count stmts.
(vect_analyze_loop_2): Adjust. Pass stmt_vec_info.length ()
to vect_analyze_slp as SLP tree size limit.
The previous version of the patch was based on the mistaken assumption that
features in /proc/cpuinfo had matching names to the feature names that gcc and
gas accept.
This patch enables the fp8 feature when the f8cvt feature is enabled, under the
assumption that fpmr is always enabled when f8cvt is.
Jonathan Wakely [Mon, 2 Dec 2024 15:13:52 +0000 (15:13 +0000)]
libstdc++: Make std::vector<bool> constructor noexcept (LWG 3778)
LWG 3778 was approved in November 2022. We already implement all the
changes except for one, which this commit does.
The new test verifies all the changes from LWG 3778, not just the one
implemented here.
libstdc++-v3/ChangeLog:
* include/bits/stl_bvector.h (vector(const allocator_type&)):
Add noexcept, as per LWG 3778.
* testsuite/23_containers/vector/bool/cons/lwg3778.cc: New test.
Jakub Jelinek [Tue, 3 Dec 2024 10:17:49 +0000 (11:17 +0100)]
tree-ssanames, match.pd: get_nonzero_bits/with_*_nonzero_bits* cleanups and improvements [PR117420]
The following patch implements the with_*_nonzero_bits* cleanups and
improvements I was talking about.
get_nonzero_bits is extended to also handle BIT_AND_EXPR (as a tree or
as SSA_NAME with BIT_AND_EXPR def_stmt), new function is added for the
bits known to be set (get_known_nonzero_bits) and the match.pd predicates
are renamed and adjusted, so that there is no confusion on which one to
use (one is named and documented to be internal), changed so that it can be
used only as a simple predicate, not match some operands, and that it doesn't
try to match twice for the GIMPLE case (where SSA_NAME with integral or pointer
type matches, but SSA_NAME with BIT_AND_EXPR def_stmt matched differently).
Furthermore, get_nonzero_bits just returns the all bits set (or
get_known_nonzero_bits no bits set) fallback if the argument isn't a
SSA_NAME (nor INTEGER_CST or whatever the functions handle explicitly).
2024-12-03 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/117420
* tree-ssanames.h (get_known_nonzero_bits): Declare.
* tree-ssanames.cc (get_nonzero_bits): New wrapper function. Move old
definition to ...
(get_nonzero_bits_1): ... here, add static. Change widest_int in
function comment to wide_int.
(get_known_nonzero_bits_1, get_known_nonzero_bits): New functions.
* match.pd (with_possible_nonzero_bits2): Rename to ...
(with_possible_nonzero_bits): ... this. Guard the bit_and case with
#if GENERIC. Change to a normal match predicate without parameters.
Rename the old with_possible_nonzero_bits match to ...
(with_possible_nonzero_bits_1): ... this.
(with_certain_nonzero_bits2): Remove.
(with_known_nonzero_bits_1, with_known_nonzero_bits): New match
predicates.
(X == C (or X & Z == Y | C) is impossible if ~nonzero(X) & C != 0):
Use with_known_nonzero_bits@0 instead of
(with_certain_nonzero_bits2 @1), use with_possible_nonzero_bits@0
instead of (with_possible_nonzero_bits2 @0) and
get_known_nonzero_bits (@1) instead of wi::to_wide (@1).
Jakub Jelinek [Tue, 3 Dec 2024 10:16:37 +0000 (11:16 +0100)]
bitintlower: Fix up ?ROTATE_EXPR lowering [PR117847]
In the ?ROTATE_EXPR lowering I forgot to handle rotation by 0 correctly.
INTEGER_CST 0 is very unlikely, it would be probably folded away, but
a non-constant count can't use just p - n because then the shift count
is out of bounds for zero.
In the FE I use n == 0 ? x : (x << n) | (x >> (p - n)) but bitintlower
here isn't prepared at this point to have bb split and am not sure if
using COND_EXPR is a good idea either, so the patch uses (p - n) % p.
Perhaps I should just disable lowering the rotate in the FE for the
non-mode precision BITINT_TYPEs too.
2024-12-03 Jakub Jelinek <jakub@redhat.com>
PR middle-end/117847
* gimple-lower-bitint.cc (gimple_lower_bitint) <case LROTATE_EXPR>:
Use m = (p - n) % p instead of m = p - n for the other shift count.
Tobias Burnus [Tue, 3 Dec 2024 10:02:03 +0000 (11:02 +0100)]
OpenMP: 'allocate' directive - fixes for 'alignof' and [[omp::decl]]
Fixed a check to permit [[omp::decl(allocate,...)]] parsing in C.
Additionaly, we discussed that 'allocate align' should not affect
'alignof' to avoid issues like with:
int a;
_Alignas(_Alignof(a)) int b;
#pragma omp allocate(a) align(128)
_Alignas(_Alignof(a)) int c;
Thus, the alignment is no longer set in the C and Fortran front ends,
but for static variables now in varpool_node::finalize_decl.
(For stack variables, the alignment is handled in gimplify_bind_expr.)
NOTE: 'omp allocate' is not yet supported in C++.
gcc/c/ChangeLog:
* c-parser.cc (c_parser_omp_allocate): Only check scope if
not in_omp_decl_attribute. Remove setting the alignment.
gcc/ChangeLog:
* cgraphunit.cc (varpool_node::finalize_decl): Set alignment
based on OpenMP's 'omp allocate' attribute/directive.
gcc/fortran/ChangeLog:
* trans-decl.cc (gfc_finish_var_decl): Remove setting the alignment.
libgomp/ChangeLog:
* libgomp.texi (Memory allocation): Mention (non-)effect of 'align'
on _Alignof.
* testsuite/libgomp.c/allocate-7.c: New test.
gcc/testsuite/ChangeLog:
* c-c++-common/gomp/allocate-18.c: Check that alignof is unaffected
by 'omp allocate'.
* c-c++-common/gomp/allocate-19.c: Likewise.
aarch64: Add flags field to aarch64-simd-pragma-builtins.def
This patch adds a flags field to aarch64-simd-pragma-builtins.def
and uses it to add attributes to the function declaration.
gcc/
* config/aarch64/aarch64-simd-pragma-builtins.def: Add a flags
field to each entry.
* config/aarch64/aarch64-builtins.cc: Update includes accordingly.
(aarch64_pragma_builtins_data): Add a flags field.
(aarch64_init_pragma_builtins): Use the flags field to add attributes
to the function declaration.
Saurabh Jha [Tue, 3 Dec 2024 09:54:01 +0000 (09:54 +0000)]
aarch64: Add support for AdvSIMD lut
The AArch64 FEAT_LUT extension is optional from Armv9.2-A and mandatory
from Armv9.5-A. It introduces instructions for lookup table reads with
bit indices.
This patch adds support for AdvSIMD lut intrinsics. The intrinsics for
this extension are implemented as the following builtin functions:
* vluti2{q}_lane{q}_{u8|s8|p8}
* vluti2{q}_lane{q}_{u16|s16|p16|f16|bf16}
* vluti4q_lane{q}_{u8|s8|p8}
* vluti4q_lane{q}_{u16|s16|p16|f16|bf16}_x2
We also introduced a new approach to do lane checks for AdvSIMD.
gcc/ChangeLog:
* config/aarch64/aarch64-builtins.cc
(aarch64_builtin_signatures): Add binary_lane.
(aarch64_fntype): Handle it.
(simd_types): Add 16-bit x2 types.
(aarch64_pragma_builtins_checker): New class.
(aarch64_general_check_builtin_call): Use it.
(aarch64_expand_pragma_builtin): Add support for lut unspecs.
* config/aarch64/aarch64-option-extensions.def
(AARCH64_OPT_EXTENSION): Add lut option.
* config/aarch64/aarch64-simd-pragma-builtins.def
(ENTRY_BINARY_LANE): Modify to use new ENTRY macro.
(ENTRY_TERNARY_VLUT8): Macro to declare lut intrinsics.
(ENTRY_TERNARY_VLUT16): Macro to declare lut intrinsics.
(REQUIRED_EXTENSIONS): Declare lut intrinsics.
* config/aarch64/aarch64-simd.md
(@aarch64_<vluti_uns_op><VLUT:mode><VB:mode>): Instruction
pattern for luti2 and luti4 intrinsics.
(@aarch64_lutx2<VLUT:mode><VB:mode>): Instruction pattern for
luti4x2 intrinsics.
* config/aarch64/aarch64.h
(TARGET_LUT): lut flag.
* config/aarch64/iterators.md: Iterators and attributes for lut.
* doc/invoke.texi: Document extension in AArch64 Options.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/simd/lut-incorrect-range.c: New test.
* gcc.target/aarch64/simd/lut-no-flag.c: New test.
* gcc.target/aarch64/simd/lut.c: New test.
Co-authored-by: Vladimir Miloserdov <vladimir.miloserdov@arm.com> Co-authored-by: Richard Sandiford <richard.sandiford@arm.com>
Saurabh Jha [Tue, 3 Dec 2024 09:54:00 +0000 (09:54 +0000)]
aarch64: Refactor AdvSIMD intrinsics
Refactor AdvSIMD intrinsics defined using the new pragma-based approach
so that it is more extensible.
Introduce a new struct, simd_type, which defines types using a mode and
qualifiers, and use objects of this struct in the declaration of intrinsics
in the aarch64-simd-pragma-builtins.def file.
Change aarch64_pragma_builtins_data struct to support return type and
argument types.
Refactor aarch64_fntype and aarch64_expand_pragma_builtin so that it
initialises corresponding vectors in a loop. As we add intrinsics with
more arguments, these functions won't need to change to support those.
gcc/ChangeLog:
* config/aarch64/aarch64-builtins.cc
(ENTRY): Modify to add support of return and argument types.
(struct simd_type): New struct to declare types using mode and
qualifiers.
(struct aarch64_pragma_builtins_data): Replace mode with
the array of types to support return and argument types.
(aarch64_fntype): Modify to handle different signatures.
(aarch64_expand_pragma_builtin): Modify to handle different
signatures.
* config/aarch64/aarch64-simd-pragma-builtins.def
(ENTRY_VHSDF): Rename to ENTRY_BINARY_VHSDF.
(ENTRY_BINARY): New macro to declare binary intrinsics.
(ENTRY_BINARY_VHSDF): Remove signature argument and use
ENTRY_BINARY.
Co-authored-by: Vladimir Miloserdov <vladimir.miloserdov@arm.com> Co-authored-by: Richard Sandiford <richard.sandiford@arm.com>
We had a function called aarch64_vq_mode, where "vq" stood for "vector
quadword". It was used by aarch64_simd_container_mode (from which it
originated) and in preparation for various SVE ...Q instructions.
It's useful for follow-on patches if we also split out the handling
of 64-bit modes from aarch64_simd_container_mode. Keeping to the
same naming scheme would replace "q" with "d", but that has
unfortunate connotations, and doesn't AFAIK correspond to any
actual SVE mnemonics.
This patch therefore splits the handling out into a function called
aarch64_v64_mode and renames aarch64_vq_mode to aarch64_v128_mode for
consistency. I didn't rename the "vq" local variables, since I think
those names make sense in context.
aarch64: Move some diagnostic functions to aarch64.cc
Some of the diagnostics reported for SVE builtins would also be
useful for Advanced SIMD builtins, so this patch moves them from
aarch64-sve-builtins.cc to aarch64.cc. I put them in a new aarch64
namespace for now -- perhaps in future they should be generic.
gcc/
* config/aarch64/aarch64-sve-builtins.cc (report_non_ice)
(report_out_of_range, report_neither_nor, report_not_one_of)
(report_not_enum): Move to...
* config/aarch64/aarch64.cc: ...here, putting them in the aarch64
namespace, and...
* config/aarch64/aarch64-protos.h: ...declare them here.
Pan Li [Fri, 29 Nov 2024 12:33:19 +0000 (20:33 +0800)]
Match: Refactor the unsigned SAT_SUB match patterns [NFC]
This patch would like to refactor the all unsigned SAT_SUB patterns, aka:
* Extract type check outside.
* Re-arrange the related match pattern forms together.
The below test suites are passed for this patch.
* The rv64gcv fully regression test.
* The x86 bootstrap test.
* The x86 fully regression test.
gcc/ChangeLog:
* match.pd: Refactor sorts of unsigned SAT_SUB match patterns.
Pan Li [Tue, 3 Dec 2024 06:08:07 +0000 (14:08 +0800)]
RISC-V: Fix incorrect optimization options passing to reduc and ternop
Like the strided load/store, the testcases of vector reduce and ternop
are designed to pick up different sorts of optimization options but
actually these option are ignored according to the Execution log of
the gcc.log.
This patch would like to make it correct almost the same as what we
fixed for strided load/store.
The below test suites are passed for this patch.
* The rv64gcv fully regression test.
It is test only patch and obvious up to a point, will commit it
directly if no comments in next 48H.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/rvv.exp: Fix the incorrect optimization
options passing to testcases.
Heiko Eißfeldt [Tue, 3 Dec 2024 08:47:59 +0000 (09:47 +0100)]
replace atoi with strtoul in varasm.cc (decode_reg_name_and_count) [PR114540]
The function uses atoi, which can silently return valid numbers even for
some too large numbers in the string.
Furthermore, the verification that all the characters in asmspec are
decimal digits can be simplified when using strotoul, we can check just
the first digit and whether the end pointer points to '\0'.
2024-12-03 Heiko Eißfeldt <heiko@hexco.de>
PR middle-end/114540
* varasm.cc (decode_reg_name_and_count): Use strtoul instead of atoi
and simplify verification that the whole asmspec contains just decimal
digits.
* gcc.dg/pr114540.c: New test.
Signed-off-by: Heiko Eißfeldt <heiko@hexco.de> Co-authored-by: Jakub Jelinek <jakub@redhat.com>
With SLP forced we fail to consider using single-lane SLP for a case
that we still end up discovering as hybrid (in the PR in question
this is because we run into the SLP discovery limit due to excessive
association).