[gcc(refs/users/meissner/heads/work179-vpair)] Rewrite vector-pair.h to use macros.
https://gcc.gnu.org/g:19ed2c59d89de89c3c4473325636d8778137712e commit 19ed2c59d89de89c3c4473325636d8778137712e Author: Michael Meissner Date: Tue Oct 1 23:15:16 2024 -0400 Rewrite vector-pair.h to use macros. 2024-10-01 Michael Meissner * config/rs6000/rs6000-c.cc (rs6000_target_modify_macros): Define __VPAIR__ if MMA is available. * config/rs6000/vector-pair.h: Rewrite to only have one function definition, and to use macros to to switch between the 3 implementations. Delete vector_pair_t. Diff: --- gcc/config/rs6000/rs6000-c.cc | 8 +- gcc/config/rs6000/vector-pair.h | 864 +++- 2 files changed, 244 insertions(+), 628 deletions(-) diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc index 82826f96a8e7..77bee8fc8786 100644 --- a/gcc/config/rs6000/rs6000-c.cc +++ b/gcc/config/rs6000/rs6000-c.cc @@ -590,9 +590,13 @@ rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags, if (rs6000_cpu == PROCESSOR_CELL) rs6000_define_or_undefine_macro (define_p, "__PPU__"); - /* Tell the user if we support the MMA instructions. */ + /* Tell the user if we support the MMA instructions. Also tell vector-pair.h + that we have the vector pair built-in function support. */ if ((flags & OPTION_MASK_MMA) != 0) -rs6000_define_or_undefine_macro (define_p, "__MMA__"); +{ + rs6000_define_or_undefine_macro (define_p, "__MMA__"); + rs6000_define_or_undefine_macro (define_p, "__VPAIR__"); +} /* Whether pc-relative code is being generated. */ if ((flags & OPTION_MASK_PCREL) != 0) rs6000_define_or_undefine_macro (define_p, "__PCREL__"); diff --git a/gcc/config/rs6000/vector-pair.h b/gcc/config/rs6000/vector-pair.h index e39e11fb3537..c36952003551 100644 --- a/gcc/config/rs6000/vector-pair.h +++ b/gcc/config/rs6000/vector-pair.h @@ -42,7 +42,6 @@ union __vpair_union { vector unsigned char __vp_uc[2]; }; -typedef union __vpair_unionvector_pair_t; typedef union __vpair_unionvector_pair_f64_t; typedef union __vpair_unionvector_pair_f32_t; @@ -58,327 +57,239 @@ typedef union __vpair_union vector_pair_f32_t; #endif #endif - -/* ISA 3.1 (power10/power11) support with explicit vector pair type and - built-in functions for the vector pair operations. */ +#undef __VPAIR_SPLAT +#undef __VPAIR_UNARY +#undef __VPAIR_BINARY +#undef __VPAIR_FMA -#if __VPAIR_BUILTIN__ && __MMA__ +#undef __VPAIR_F64_UNARY +#undef __VPAIR_F64_BINARY +#undef __VPAIR_F64_FMA -/* vector pair double operations on power10/power11 with vector pair built-in - functions. */ -static inline void -vpair_f64_splat (vector_pair_f64_t *__r, -double __x) -{ - __r->__vpair = __builtin_vpair_f64_splat (__x); -} +#undef __VPAIR_F32_UNARY +#undef __VPAIR_F32_BINARY +#undef __VPAIR_F32_FMA -static inline void -vpair_f64_abs (vector_pair_f64_t *__r, - const vector_pair_f64_t *__a) -{ - __r->__vpair = __builtin_vpair_f64_abs (__a->__vpair); -} +/* Operations using a built-in vector pair function. */ +#if __MMA__ && __VPAIR_BUILTIN__ -static inline void -vpair_f64_nabs (vector_pair_f64_t *__r, - const vector_pair_f64_t *__a) -{ - __r->__vpair = __builtin_vpair_f64_nabs (__a->__vpair); -} +#define __VPAIR_SPLAT(R, X, VP_FUNC, VEC) \ + (R)->__vpair = VP_FUNC ((X)) -static inline void -vpair_f64_neg (vector_pair_f64_t *__r, - const vector_pair_f64_t *__a) -{ - __r->__vpair = __builtin_vpair_f64_neg (__a->__vpair); -} +#define __VPAIR_UNARY(R, A, VP_FUNC, OPCODE, VEC, VEC_FUNC)\ + (R)->__vpair = VP_FUNC ((A)->__vpair) -static inline void -vpair_f64_sqrt (vector_pair_f64_t *__r, - const vector_pair_f64_t *__a) -{ - __r->__vpair = __builtin_vpair_f64_sqrt (__a->__vpair); -} +#define __VPAIR_BINARY(R, A, B, VP_FUNC, OPCODE, VEC, VEC_FUNC) \ + (R)->__vpair = VP_FUNC ((A)->__vpair, (B)->__vpair) -static inline void -vpair_f64_add (vector_pair_f64_t *__r, - const vector_pair_f64_t *__a, - const vector_pair_f64_t *__b) -{ - __r->__vpair = __builtin_vpair_f64_add (__a->__vpair, __b->__vpair); -} +#define __VPAIR_FMA(R, A, B, C, VP_FUNC, OPCODE, VEC, VEC_FUNC) \ + (R)->__vpair = VP_FUNC ((A)->__vpair, (B)->__vpair, (C)->__vpair) -static inline void -vpair_f64_max (vector_pair_f64_t *__r, - const vector_pair_f64_t *__a, - const vector_pair_f64_t *__b) -{ - __r->__vpair = __builtin_vpair_f64_max (__a->__vpair, __b->__vpair); -} +/* Operations using a vector pair and __asm__operations. */ +#elif __MMA__ && !__VPAIR_NOP10__ -static inline void -vpair_f64_min (vector_pair_f64_t *__r, - const vector_pair_f64_t *__a, - const vector_pair_f64_t *__b) -{ -
[gcc(refs/users/meissner/heads/work179-vpair)] Update ChangeLog.*
https://gcc.gnu.org/g:f48e6de9766c8c775a894d2445b5ce9199e3bf45 commit f48e6de9766c8c775a894d2445b5ce9199e3bf45 Author: Michael Meissner Date: Tue Oct 1 23:16:44 2024 -0400 Update ChangeLog.* Diff: --- gcc/ChangeLog.vpair | 15 +++ 1 file changed, 15 insertions(+) diff --git a/gcc/ChangeLog.vpair b/gcc/ChangeLog.vpair index 9fec75006e9e..285eda695f6b 100644 --- a/gcc/ChangeLog.vpair +++ b/gcc/ChangeLog.vpair @@ -1,3 +1,18 @@ + Branch work179-vpair, patch #309 + +Rewrite vector-pair.h to use macros. + +2024-10-01 Michael Meissner + + * config/rs6000/rs6000-c.cc (rs6000_target_modify_macros): Define + __VPAIR__ if MMA is available. + * config/rs6000/vector-pair.h: Rewrite to only have one function + definition, and to use macros to to switch between the 3 + implementations. Delete vector_pair_t. + + Branch work179-vpair, patch #308 was reverted + + Branch work179-vpair, patch #307 Remove re-inclusion support; Fix various typos; Spacing.
[gcc(refs/users/meissner/heads/work179-vpair)] Remove splitting vpair built-ins.
https://gcc.gnu.org/g:ef2f57c1b666eacba9770b5db9ebdcde2d484cb9 commit ef2f57c1b666eacba9770b5db9ebdcde2d484cb9 Author: Michael Meissner Date: Tue Oct 1 04:14:55 2024 -0400 Remove splitting vpair built-ins. 2024-10-01 Michael Meissner gcc/ * config/rs6000/rs6000-protos.h (enum vpair_split_unary): Delete. (vpair_split_unary): Likewise. (vpair_split_binary): Likewise. (enum vpair_split_fma): Likewise. (vpair_split_fma): Likewise. * config/rs6000/rs6000.cc (vpair_split_unary): Likewise. (vpair_split_binary): Likewise. (vpair_split_fma): Likewise. * config/rs6000/vector-pair.md (vpair_spdp): New attribute. (vpair_insn): Likewise. (vpair__2): Convert from define_insn_and_split to define_insn. (vpair_nabs_2): Likewise. (vpair__3): Likewise. (vpair_fma_4): Likewise. (vpair_fms_4): Likewise. (vpair_nfma_4): Likewise. (vpair_nfms_4): Likewise. Diff: --- gcc/config/rs6000/rs6000-protos.h | 25 --- gcc/config/rs6000/rs6000.cc | 138 -- gcc/config/rs6000/vector-pair.md | 95 +++--- 3 files changed, 38 insertions(+), 220 deletions(-) diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index bab5fb437c27..da658cd5ab2e 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -161,31 +161,6 @@ extern bool rs6000_pcrel_p (void); extern bool rs6000_fndecl_pcrel_p (const_tree); extern void rs6000_output_addr_vec_elt (FILE *, int); -/* If we are splitting a vector pair unary operator into two separate vector - operations, we need to generate a NEG if this is NABS. */ - -enum vpair_split_unary { - VPAIR_SPLIT_NORMAL, /* No extra processing is needed. */ - VPAIR_SPLIT_NEGATE /* Wrap operation with a NEG. */ -}; - -extern void vpair_split_unary (rtx [], machine_mode, enum rtx_code, - enum vpair_split_unary); -extern void vpair_split_binary (rtx [], machine_mode, enum rtx_code); - -/* When we are splitting a vector pair FMA operation into two vector operations, we - may need to modify the code generated. This enumeration encodes the - different choices. */ - -enum vpair_split_fma { - VPAIR_SPLIT_FMA, /* Fused multiply-add. */ - VPAIR_SPLIT_FMS, /* Fused multiply-subtract. */ - VPAIR_SPLIT_NFMA,/* Fused negate multiply-add. */ - VPAIR_SPLIT_NFMS /* Fused negate multiply-subtract. */ -}; - -extern void vpair_split_fma (rtx [], machine_mode, enum vpair_split_fma); - /* Different PowerPC instruction formats that are used by GCC. There are various other instruction formats used by the PowerPC hardware, but these formats are not currently used by GCC. */ diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 2be11e542a06..8afa19fd38ac 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -29610,144 +29610,6 @@ rs6000_opaque_type_invalid_use_p (gimple *stmt) return false; } -/* Split vector pair unary operations. */ - -void -vpair_split_unary (rtx operands[], /* Dest, input. */ - machine_mode vmode, /* Vector mode. */ - enum rtx_code code, /* Operator code. */ - enum vpair_split_unary action) /* Action to take. */ -{ - rtx op0 = operands[0]; - machine_mode mode0 = GET_MODE (op0); - gcc_assert (GET_MODE_SIZE (mode0) == 32); - rtx op0_a = simplify_gen_subreg (vmode, op0, mode0, 0); - rtx op0_b = simplify_gen_subreg (vmode, op0, mode0, 16); - - rtx op1 = operands[1]; - machine_mode mode1 = GET_MODE (op1); - gcc_assert (GET_MODE_SIZE (mode0) == 32); - rtx op1_a = simplify_gen_subreg (vmode, op1, mode1, 0); - rtx op1_b = simplify_gen_subreg (vmode, op1, mode1, 16); - - rtx operation_a = gen_rtx_fmt_e (code, vmode, op1_a); - rtx operation_b = gen_rtx_fmt_e (code, vmode, op1_b); - - if (action == VPAIR_SPLIT_NEGATE) -{ - operation_a = gen_rtx_NEG (vmode, operation_a); - operation_b = gen_rtx_NEG (vmode, operation_b); -} - - emit_insn (gen_rtx_SET (op0_a, operation_a)); - emit_insn (gen_rtx_SET (op0_b, operation_b)); - return; -} - -/* Split vector pair binary operations. */ - -void -vpair_split_binary (rtx operands[],/* Dest, 2 inputs. */ - machine_mode vmode, /* Vector mode. */ - enum rtx_code code) /* Operator code. */ -{ - rtx op0 = operands[0]; - machine_mode mode0 = GET_MODE (op0); - gcc_assert (GET_MODE_SIZE (mode0) == 32); - rtx op0_a = simplify_gen_subreg (vmode, op0, mode0, 0); - rtx op0_b = simplify_gen_subreg (vmode, op0, mode0,
[gcc r15-3984] range-cache: Fix ICE on SSA_NAME with def_stmt not yet in the IL [PR116898]
https://gcc.gnu.org/g:bdbd0607d5933cdecbf7e009a42f1d9486dddf44 commit r15-3984-gbdbd0607d5933cdecbf7e009a42f1d9486dddf44 Author: Jakub Jelinek Date: Tue Oct 1 09:49:49 2024 +0200 range-cache: Fix ICE on SSA_NAME with def_stmt not yet in the IL [PR116898] Some passes like the bitint lowering queue some statements on edges and only commit them at the end of the pass. If they use ranger at the same time, the ranger might see such SSA_NAMEs and ICE on those. The following patch instead just punts on them. 2024-10-01 Jakub Jelinek PR middle-end/116898 * gimple-range-cache.cc (ranger_cache::block_range): If a SSA_NAME with NULL def_bb isn't SSA_NAME_IS_DEFAULT_DEF, return false instead of failing assertion. Formatting fix. * gcc.dg/bitint-110.c: New test. Diff: --- gcc/gimple-range-cache.cc | 9 ++--- gcc/testsuite/gcc.dg/bitint-110.c | 20 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 43949894cbed..c0b8916e85af 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -1284,13 +1284,16 @@ ranger_cache::block_range (vrange &r, basic_block bb, tree name, bool calc) gimple *def_stmt = SSA_NAME_DEF_STMT (name); basic_block def_bb = NULL; if (def_stmt) - def_bb = gimple_bb (def_stmt);; + def_bb = gimple_bb (def_stmt); if (!def_bb) { // If we get to the entry block, this better be a default def // or range_on_entry was called for a block not dominated by - // the def. - gcc_checking_assert (SSA_NAME_IS_DEFAULT_DEF (name)); + // the def. But it could be also SSA_NAME defined by a statement + // not yet in the IL (such as queued edge insertion), in that case + // just punt. + if (!SSA_NAME_IS_DEFAULT_DEF (name)) + return false; def_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun); } diff --git a/gcc/testsuite/gcc.dg/bitint-110.c b/gcc/testsuite/gcc.dg/bitint-110.c new file mode 100644 index ..4ba2f93856e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-110.c @@ -0,0 +1,20 @@ +/* PR middle-end/116898 */ +/* { dg-do compile { target bitint575 } } */ +/* { dg-options "-O -finstrument-functions -fnon-call-exceptions" } */ + +_BitInt(127) a; +_BitInt(511) b; + +void +foo (_BitInt(31) c) +{ + do +{ + c %= b; +again: +} + while (c); + a /= 0; /* { dg-warning "division by zero" } */ + c -= a; + goto again; +}
[gcc r15-3997] aarch64: Introduce new unspecs for smax/smin
https://gcc.gnu.org/g:ac4cdf5cb43c0b09e81760e2a1902ceebcf1a135 commit r15-3997-gac4cdf5cb43c0b09e81760e2a1902ceebcf1a135 Author: Saurabh Jha Date: Mon Sep 30 10:37:16 2024 + aarch64: Introduce new unspecs for smax/smin Introduce two new unspecs, UNSPEC_COND_SMAX and UNSPEC_COND_SMIN, corresponding to rtl operators smax and smin. UNSPEC_COND_SMAX is used to generate fmaxnm instruction and UNSPEC_COND_SMIN is used to generate fminnm instruction. With these new unspecs, we can generate SVE2 max/min instructions using existing generic unpredicated and predicated instruction patterns that use optab attribute. Thus, we have removed specialised instruction patterns for max/min instructions that were using SVE_COND_FP_MAXMIN_PUBLIC iterator. No new test cases as the existing test cases should be enough to test this refactoring. gcc/ChangeLog: * config/aarch64/aarch64-sve.md (3): Remove this instruction pattern. (cond_): Remove this instruction pattern. * config/aarch64/iterators.md: New unspecs and changes to iterators and attrs to use the new unspecs Diff: --- gcc/config/aarch64/aarch64-sve.md | 33 -- gcc/config/aarch64/iterators.md | 73 --- 2 files changed, 45 insertions(+), 61 deletions(-) diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index f6c7c2f4cb31..ec1d059a2b1b 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -6600,39 +6600,6 @@ ;; - FMINNM ;; - -;; Unpredicated fmax/fmin (the libm functions). The optabs for the -;; smax/smin rtx codes are handled in the generic section above. -(define_expand "3" - [(set (match_operand:SVE_FULL_F 0 "register_operand") - (unspec:SVE_FULL_F - [(match_dup 3) - (const_int SVE_RELAXED_GP) - (match_operand:SVE_FULL_F 1 "register_operand") - (match_operand:SVE_FULL_F 2 "aarch64_sve_float_maxmin_operand")] - SVE_COND_FP_MAXMIN_PUBLIC))] - "TARGET_SVE" - { -operands[3] = aarch64_ptrue_reg (mode); - } -) - -;; Predicated fmax/fmin (the libm functions). The optabs for the -;; smax/smin rtx codes are handled in the generic section above. -(define_expand "cond_" - [(set (match_operand:SVE_FULL_F 0 "register_operand") - (unspec:SVE_FULL_F - [(match_operand: 1 "register_operand") - (unspec:SVE_FULL_F -[(match_dup 1) - (const_int SVE_RELAXED_GP) - (match_operand:SVE_FULL_F 2 "register_operand") - (match_operand:SVE_FULL_F 3 "aarch64_sve_float_maxmin_operand")] -SVE_COND_FP_MAXMIN_PUBLIC) - (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero")] - UNSPEC_SEL))] - "TARGET_SVE" -) - ;; Predicated floating-point maximum/minimum. (define_insn "@aarch64_pred_" [(set (match_operand:SVE_FULL_F 0 "register_operand") diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index c2fcd18306e4..0836dee61c9f 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -881,6 +881,8 @@ UNSPEC_COND_FSQRT ; Used in aarch64-sve.md. UNSPEC_COND_FSUB ; Used in aarch64-sve.md. UNSPEC_COND_SCVTF ; Used in aarch64-sve.md. +UNSPEC_COND_SMAX ; Used in aarch64-sve.md. +UNSPEC_COND_SMIN ; Used in aarch64-sve.md. UNSPEC_COND_UCVTF ; Used in aarch64-sve.md. UNSPEC_LASTA ; Used in aarch64-sve.md. UNSPEC_LASTB ; Used in aarch64-sve.md. @@ -3081,15 +3083,18 @@ (define_int_iterator SVE_COND_FCVTI [UNSPEC_COND_FCVTZS UNSPEC_COND_FCVTZU]) (define_int_iterator SVE_COND_ICVTF [UNSPEC_COND_SCVTF UNSPEC_COND_UCVTF]) -(define_int_iterator SVE_COND_FP_BINARY [UNSPEC_COND_FADD -UNSPEC_COND_FDIV -UNSPEC_COND_FMAX -UNSPEC_COND_FMAXNM -UNSPEC_COND_FMIN -UNSPEC_COND_FMINNM -UNSPEC_COND_FMUL -UNSPEC_COND_FMULX -UNSPEC_COND_FSUB]) +(define_int_iterator SVE_COND_FP_BINARY + [UNSPEC_COND_FADD + UNSPEC_COND_FDIV + UNSPEC_COND_FMAX + UNSPEC_COND_FMAXNM + UNSPEC_COND_FMIN + UNSPEC_COND_FMINNM + UNSPEC_COND_FMUL + UNSPEC_COND_FMULX + UNSPEC_COND_FSUB + UNSPEC_COND_SMAX + UNSPEC_COND_SMIN]) ;; Same as SVE_COND_FP_BINARY, but without codes that have a dedicated ;; 3 expander. @@ -3100,7 +3105,9 @@ UNSPEC_COND_FMINNM UNSPEC_COND_FMUL UNSPEC_
[gcc r15-3998] AVR: avr-passes.cc - Fix a build warning.
https://gcc.gnu.org/g:5e41e8fd86794319f05eb1d76822021786b81a91 commit r15-3998-g5e41e8fd86794319f05eb1d76822021786b81a91 Author: Georg-Johann Lay Date: Tue Oct 1 20:25:26 2024 +0200 AVR: avr-passes.cc - Fix a build warning. gcc/ * config/avr/avr-passes.cc (avr_split_fake_addressing_move): Fix a build warning. Diff: --- gcc/config/avr/avr-passes.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/config/avr/avr-passes.cc b/gcc/config/avr/avr-passes.cc index ad913ddd4afc..205b490950d7 100644 --- a/gcc/config/avr/avr-passes.cc +++ b/gcc/config/avr/avr-passes.cc @@ -1788,7 +1788,8 @@ avr_split_fake_addressing_move (rtx_insn * /*insn*/, rtx *xop) HOST_WIDE_INT add = 0, sub = 0; int msize = GET_MODE_SIZE (mode); - AVR_LdSt_Props ap { REGNO (base), store_p, volatile_p, ADDR_SPACE_GENERIC }; + AVR_LdSt_Props ap { (int) REGNO (base), store_p, volatile_p, + ADDR_SPACE_GENERIC }; switch (addr_code) {
[gcc/devel/nothrow-detection] Updated tree-eh.h
https://gcc.gnu.org/g:132a0acfde7975c0b6f74b6a456ecc8ed46face4 commit 132a0acfde7975c0b6f74b6a456ecc8ed46face4 Author: Pranil Dey Date: Tue Oct 1 10:32:27 2024 +0530 Updated tree-eh.h Diff: --- gcc/tree-eh.h | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h index 978bc6228bf0..618375313ec7 100644 --- a/gcc/tree-eh.h +++ b/gcc/tree-eh.h @@ -32,6 +32,7 @@ extern bool remove_stmt_from_eh_lp (gimple *); extern int lookup_stmt_eh_lp_fn (struct function *, const gimple *); extern int lookup_stmt_eh_lp (const gimple *); extern bool make_eh_dispatch_edges (geh_dispatch *); +extern bool same_or_derived_type (tree, tree); extern bool match_lp (eh_landing_pad, vec *); extern void update_stmt_eh_region(gimple *); extern edge make_eh_edge (gimple *);
[gcc r15-3991] modula2: Add FindIndice to library module gm2-libs/Indexing
https://gcc.gnu.org/g:8273e31adfa1ba5f0722eb37bcc8aeca8718a472 commit r15-3991-g8273e31adfa1ba5f0722eb37bcc8aeca8718a472 Author: Gaius Mulley Date: Tue Oct 1 15:06:54 2024 +0100 modula2: Add FindIndice to library module gm2-libs/Indexing This patch introduces the procedure function FindIndice to library module Indexing. gcc/m2/ChangeLog: * gm2-libs/Indexing.def (FindIndice): New procedure function. * gm2-libs/Indexing.mod (FindIndice): Implement new procedure function. Signed-off-by: Gaius Mulley Diff: --- gcc/m2/gm2-libs/Indexing.def | 8 gcc/m2/gm2-libs/Indexing.mod | 28 2 files changed, 36 insertions(+) diff --git a/gcc/m2/gm2-libs/Indexing.def b/gcc/m2/gm2-libs/Indexing.def index f7c4676df33a..0b56043f20a7 100644 --- a/gcc/m2/gm2-libs/Indexing.def +++ b/gcc/m2/gm2-libs/Indexing.def @@ -144,4 +144,12 @@ PROCEDURE ForeachIndiceInIndexDo (i: Index; p: IndexProcedure) ; PROCEDURE IsEmpty (i: Index) : BOOLEAN ; +(* + FindIndice - returns the indice containing a. +It returns zero if a is not found in array i. +*) + +PROCEDURE FindIndice (i: Index; a: ADDRESS) : CARDINAL ; + + END Indexing. diff --git a/gcc/m2/gm2-libs/Indexing.mod b/gcc/m2/gm2-libs/Indexing.mod index 08af13484d08..7bcaf87e278e 100644 --- a/gcc/m2/gm2-libs/Indexing.mod +++ b/gcc/m2/gm2-libs/Indexing.mod @@ -342,6 +342,34 @@ BEGIN END IncludeIndiceIntoIndex ; +(* + FindIndice - returns the indice containing a. +It returns zero if a is not found in array i. +*) + +PROCEDURE FindIndice (i: Index; a: ADDRESS) : CARDINAL ; +VAR + j: CARDINAL ; + p: PtrToAddress ; + b: PtrToByte ; +BEGIN + WITH i^ DO + j := Low ; + b := ArrayStart ; + WHILE j <= High DO + p := VAL (PtrToAddress, b) ; + INC (b, TSIZE (ADDRESS)) ; + IF p^ = a + THEN +RETURN j + END ; + INC (j) + END + END ; + RETURN 0 +END FindIndice ; + + (* ForeachIndiceInIndexDo - for each j indice of i, call procedure p(i[j]) *)
[gcc r15-3987] tree-optimization/116905 - ICE with bogus range ops
https://gcc.gnu.org/g:60fa7f51c84f042af70a3feea14236c102d6a9c2 commit r15-3987-g60fa7f51c84f042af70a3feea14236c102d6a9c2 Author: Richard Biener Date: Tue Oct 1 11:22:17 2024 +0200 tree-optimization/116905 - ICE with bogus range ops The following avoids querying ranges of vector entities. PR tree-optimization/116905 * tree-vect-stmts.cc (supportable_indirect_convert_operation): Fix guard for vect_get_range_info. * gcc.dg/pr116905.c: New testcase. Diff: --- gcc/testsuite/gcc.dg/pr116905.c | 14 ++ gcc/tree-vect-stmts.cc | 6 -- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/gcc.dg/pr116905.c b/gcc/testsuite/gcc.dg/pr116905.c new file mode 100644 index ..0a2b96ac1c16 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr116905.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target float16 } */ +/* { dg-options "-frounding-math" } */ +/* { dg-additional-options "-mavx" { target avx } } */ + +typedef __attribute__((__vector_size__(16))) _Float16 F; +typedef __attribute__((__vector_size__(32))) int V; +F f; + +void +foo() +{ + f += __builtin_convertvector((V){3307}, F); +} diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 540a9b733081..b880f0507158 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -14803,8 +14803,10 @@ supportable_indirect_convert_operation (code_helper code, In the future, if it is supported, changes may need to be made to this part, such as checking the RANGE of each element in the vector. */ - if ((TREE_CODE (op0) == SSA_NAME && !SSA_NAME_RANGE_INFO (op0)) - || !vect_get_range_info (op0, &op_min_value, &op_max_value)) + if (TREE_CODE (op0) != SSA_NAME + || !SSA_NAME_RANGE_INFO (op0) + || !vect_get_range_info (op0, &op_min_value, + &op_max_value)) break; if (cvt_type == NULL_TREE
[gcc r15-3993] c++: introduce __builtin_is_virtual_base_of
https://gcc.gnu.org/g:1b7cfa715c6c02db6ef587c87757d7792fc43423 commit r15-3993-g1b7cfa715c6c02db6ef587c87757d7792fc43423 Author: Giuseppe D'Angelo Date: Tue Oct 1 13:31:00 2024 +0200 c++: introduce __builtin_is_virtual_base_of P2985R0 (C++26) introduces std::is_virtual_base_of; this is the compiler builtin that will back up the library trait (which strictly requires compiler support). The name has been chosen to match LLVM/MSVC's, as per the discussion here: https://github.com/llvm/llvm-project/issues/98310 The actual user-facing type trait in libstdc++ will be added later. gcc/cp/ChangeLog: * constraint.cc (diagnose_trait_expr): New diagnostic. * cp-trait.def (IS_VIRTUAL_BASE_OF): New builtin. * cp-tree.h (enum base_access_flags): Add a new flag to be able to request a search for a virtual base class. * cxx-pretty-print.cc (pp_cxx_userdef_literal): Update the list of GNU extensions to the grammar. * search.cc (struct lookup_base_data_s): Add a field to request searching for a virtual base class. (dfs_lookup_base): Add the ability to look for a virtual base class. (lookup_base): Forward the flag to dfs_lookup_base. * semantics.cc (trait_expr_value): Implement the builtin by calling lookup_base with the new flag. (finish_trait_expr): Handle the new builtin. gcc/ChangeLog: * doc/extend.texi: Document the new __builtin_is_virtual_base_of builtin; amend the docs for __is_base_of. gcc/testsuite/ChangeLog: * g++.dg/ext/is_virtual_base_of.C: New test. * g++.dg/ext/is_virtual_base_of_diagnostic.C: New test. Signed-off-by: Giuseppe D'Angelo Reviewed-by: Jason Merrill Diff: --- gcc/doc/extend.texi| 15 ++ gcc/cp/cp-tree.h | 3 +- gcc/cp/constraint.cc | 3 + gcc/cp/cxx-pretty-print.cc | 2 + gcc/cp/search.cc | 15 +- gcc/cp/semantics.cc| 12 ++ gcc/testsuite/g++.dg/ext/is_virtual_base_of.C | 163 + .../g++.dg/ext/is_virtual_base_of_diagnostic.C | 15 ++ gcc/cp/cp-trait.def| 1 + 9 files changed, 225 insertions(+), 4 deletions(-) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index f0d8eb59dded..f46c3df33030 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -29984,12 +29984,27 @@ If @var{base_type} is a base class of @var{derived_type} Top-level cv-qualifications of @var{base_type} and @var{derived_type} are ignored. For the purposes of this trait, a class type is considered is own base. +The trait is @code{true} even if @var{base_type} is an ambiguous or +inaccessible base class of @var{derived_type}. Requires: if @code{__is_class (base_type)} and @code{__is_class (derived_type)} are @code{true} and @var{base_type} and @var{derived_type} are not the same type (disregarding cv-qualifiers), @var{derived_type} shall be a complete type. A diagnostic is produced if this requirement is not met. @enddefbuiltin +@defbuiltin{bool __builtin_is_virtual_base_of (@var{base_type}, @var{derived_type})} +If @var{base_type} is a virtual base class of @var{derived_type} +([class.derived], [class.mi]) then the trait is @code{true}, +otherwise it is @code{false}. +Top-level cv-qualifications of @var{base_type} and +@var{derived_type} are ignored. +The trait is @code{true} even if @var{base_type} is an ambiguous or +inaccessible virtual base class of @var{derived_type}. +Requires: if @code{__is_class (base_type)} and @code{__is_class (derived_type)} +are @code{true}, @var{derived_type} shall be a complete +type. A diagnostic is produced if this requirement is not met. +@enddefbuiltin + @defbuiltin{bool __is_class (@var{type})} If @var{type} is a cv-qualified class type, and not a union type ([basic.compound]) the trait is @code{true}, else it is @code{false}. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 39c065eecf6d..c5d02567cb4b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5723,7 +5723,8 @@ enum base_access_flags { ba_unique = 1 << 0, /* Must be a unique base. */ ba_check_bit = 1 << 1, /* Check access. */ ba_check = ba_unique | ba_check_bit, - ba_ignore_scope = 1 << 2 /* Ignore access allowed by local scope. */ + ba_ignore_scope = 1 << 2, /* Ignore access allowed by local scope. */ + ba_require_virtual = 1 << 3 /* Require a virtual base. */ }; /* This type is used for parameters and variables which hold diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index ebfcdefd2841..cf0e5d37571c 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3291,6
[gcc(refs/users/meissner/heads/work179-vpair)] Revert patch.
https://gcc.gnu.org/g:cbcae46e703e164b078309eca1261fb8afcf5993 commit cbcae46e703e164b078309eca1261fb8afcf5993 Author: Michael Meissner Date: Tue Oct 1 04:16:49 2024 -0400 Revert patch. 2024-10-01 Michael Meissner gcc/ * config/rs6000/rs6000-protos.h (enum vpair_split_unary): Revert. (vpair_split_unary): Likewise. (vpair_split_binary): Likewise. (enum vpair_split_fma): Likewise. (vpair_split_fma): Likewise. * config/rs6000/rs6000.cc (vpair_split_unary): Likewise. (vpair_split_binary): Likewise. (vpair_split_fma): Likewise. * config/rs6000/vector-pair.md (vpair_spdp): Delete. (vpair_insn): Likewise. (vpair__2): Revert. (vpair_nabs_2): Likewise. (vpair__3): Likewise. (vpair_fma_4): Likewise. (vpair_fms_4): Likewise. (vpair_nfma_4): Likewise. (vpair_nfms_4): Likewise. Diff: --- gcc/config/rs6000/rs6000-protos.h | 25 +++ gcc/config/rs6000/rs6000.cc | 138 ++ gcc/config/rs6000/vector-pair.md | 95 +++--- 3 files changed, 220 insertions(+), 38 deletions(-) diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index da658cd5ab2e..bab5fb437c27 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -161,6 +161,31 @@ extern bool rs6000_pcrel_p (void); extern bool rs6000_fndecl_pcrel_p (const_tree); extern void rs6000_output_addr_vec_elt (FILE *, int); +/* If we are splitting a vector pair unary operator into two separate vector + operations, we need to generate a NEG if this is NABS. */ + +enum vpair_split_unary { + VPAIR_SPLIT_NORMAL, /* No extra processing is needed. */ + VPAIR_SPLIT_NEGATE /* Wrap operation with a NEG. */ +}; + +extern void vpair_split_unary (rtx [], machine_mode, enum rtx_code, + enum vpair_split_unary); +extern void vpair_split_binary (rtx [], machine_mode, enum rtx_code); + +/* When we are splitting a vector pair FMA operation into two vector operations, we + may need to modify the code generated. This enumeration encodes the + different choices. */ + +enum vpair_split_fma { + VPAIR_SPLIT_FMA, /* Fused multiply-add. */ + VPAIR_SPLIT_FMS, /* Fused multiply-subtract. */ + VPAIR_SPLIT_NFMA,/* Fused negate multiply-add. */ + VPAIR_SPLIT_NFMS /* Fused negate multiply-subtract. */ +}; + +extern void vpair_split_fma (rtx [], machine_mode, enum vpair_split_fma); + /* Different PowerPC instruction formats that are used by GCC. There are various other instruction formats used by the PowerPC hardware, but these formats are not currently used by GCC. */ diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 8afa19fd38ac..2be11e542a06 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -29610,6 +29610,144 @@ rs6000_opaque_type_invalid_use_p (gimple *stmt) return false; } +/* Split vector pair unary operations. */ + +void +vpair_split_unary (rtx operands[], /* Dest, input. */ + machine_mode vmode, /* Vector mode. */ + enum rtx_code code, /* Operator code. */ + enum vpair_split_unary action) /* Action to take. */ +{ + rtx op0 = operands[0]; + machine_mode mode0 = GET_MODE (op0); + gcc_assert (GET_MODE_SIZE (mode0) == 32); + rtx op0_a = simplify_gen_subreg (vmode, op0, mode0, 0); + rtx op0_b = simplify_gen_subreg (vmode, op0, mode0, 16); + + rtx op1 = operands[1]; + machine_mode mode1 = GET_MODE (op1); + gcc_assert (GET_MODE_SIZE (mode0) == 32); + rtx op1_a = simplify_gen_subreg (vmode, op1, mode1, 0); + rtx op1_b = simplify_gen_subreg (vmode, op1, mode1, 16); + + rtx operation_a = gen_rtx_fmt_e (code, vmode, op1_a); + rtx operation_b = gen_rtx_fmt_e (code, vmode, op1_b); + + if (action == VPAIR_SPLIT_NEGATE) +{ + operation_a = gen_rtx_NEG (vmode, operation_a); + operation_b = gen_rtx_NEG (vmode, operation_b); +} + + emit_insn (gen_rtx_SET (op0_a, operation_a)); + emit_insn (gen_rtx_SET (op0_b, operation_b)); + return; +} + +/* Split vector pair binary operations. */ + +void +vpair_split_binary (rtx operands[],/* Dest, 2 inputs. */ + machine_mode vmode, /* Vector mode. */ + enum rtx_code code) /* Operator code. */ +{ + rtx op0 = operands[0]; + machine_mode mode0 = GET_MODE (op0); + gcc_assert (GET_MODE_SIZE (mode0) == 32); + rtx op0_a = simplify_gen_subreg (vmode, op0, mode0, 0); + rtx op0_b = simplify_gen_subreg (vmode, op0, mode0, 16); + + rtx op1 = operands[1]; + machine_mode mode1 = GET_MODE (op1); + gcc_a
[gcc r15-3989] aarch64: Add fp8 scalar types
https://gcc.gnu.org/g:35dd5cfbfd7f33b5f22ae209635f40af4ab6863c commit r15-3989-g35dd5cfbfd7f33b5f22ae209635f40af4ab6863c Author: Claudio Bantaloukas Date: Tue Oct 1 12:45:11 2024 + aarch64: Add fp8 scalar types The ACLE defines a new scalar type, __mfp8. This is an opaque 8bit types that can only be used by fp8 intrinsics. Additionally, the mfloat8_t type is made available in arm_neon.h and arm_sve.h as an alias of the same. This implementation uses an unsigned INTEGER_TYPE, with precision 8 to represent __mfp8. Conversions to int and other types are disabled via the TARGET_INVALID_CONVERSION hook. Additionally, operations that are typically available to integer types are disabled via TARGET_INVALID_UNARY_OP and TARGET_INVALID_BINARY_OP hooks. gcc/ChangeLog: * config/aarch64/aarch64-builtins.cc (aarch64_mfp8_type_node): Add node for __mfp8 type. (aarch64_mfp8_ptr_type_node): Add node for __mfp8 pointer type. (aarch64_init_fp8_types): New function to initialise fp8 types and register with language backends. * config/aarch64/aarch64.cc (aarch64_mangle_type): Add ABI mangling for new type. (aarch64_invalid_conversion): Add function implementing TARGET_INVALID_CONVERSION hook that blocks conversion to and from the __mfp8 type. (aarch64_invalid_unary_op): Add function implementing TARGET_UNARY_OP hook that blocks operations on __mfp8 other than &. (aarch64_invalid_binary_op): Extend TARGET_BINARY_OP hook to disallow operations on __mfp8 type. (TARGET_INVALID_CONVERSION): Add define. (TARGET_INVALID_UNARY_OP): Likewise. * config/aarch64/aarch64.h (aarch64_mfp8_type_node): Add node for __mfp8 type. (aarch64_mfp8_ptr_type_node): Add node for __mfp8 pointer type. * config/aarch64/arm_private_fp8.h (mfloat8_t): Add typedef. gcc/testsuite/ChangeLog: * g++.target/aarch64/fp8_mangling.C: New tests exercising mangling. * g++.target/aarch64/fp8_scalar_typecheck_2.C: New tests in C++. * gcc.target/aarch64/fp8_scalar_1.c: New tests in C. * gcc.target/aarch64/fp8_scalar_typecheck_1.c: Likewise. Diff: --- gcc/config/aarch64/aarch64-builtins.cc | 20 ++ gcc/config/aarch64/aarch64.cc | 54 ++- gcc/config/aarch64/aarch64.h | 5 + gcc/config/aarch64/arm_private_fp8.h | 2 + gcc/testsuite/g++.target/aarch64/fp8_mangling.C| 44 +++ .../g++.target/aarch64/fp8_scalar_typecheck_2.C| 381 + gcc/testsuite/gcc.target/aarch64/fp8_scalar_1.c| 134 .../gcc.target/aarch64/fp8_scalar_typecheck_1.c| 356 +++ 8 files changed, 994 insertions(+), 2 deletions(-) diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index 38b860c176a4..7d737877e0bf 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -991,6 +991,11 @@ static GTY(()) tree aarch64_simd_intOI_type_node = NULL_TREE; static GTY(()) tree aarch64_simd_intCI_type_node = NULL_TREE; static GTY(()) tree aarch64_simd_intXI_type_node = NULL_TREE; +/* The user-visible __mfp8 type, and a pointer to that type. Used + across the back-end. */ +tree aarch64_mfp8_type_node = NULL_TREE; +tree aarch64_mfp8_ptr_type_node = NULL_TREE; + /* The user-visible __fp16 type, and a pointer to that type. Used across the back-end. */ tree aarch64_fp16_type_node = NULL_TREE; @@ -1824,6 +1829,19 @@ aarch64_init_builtin_rsqrt (void) } } +/* Initialize the backend type that supports the user-visible __mfp8 + type and its relative pointer type. */ + +static void +aarch64_init_fp8_types (void) +{ + aarch64_mfp8_type_node = make_unsigned_type (8); + SET_TYPE_MODE (aarch64_mfp8_type_node, QImode); + + lang_hooks.types.register_builtin_type (aarch64_mfp8_type_node, "__mfp8"); + aarch64_mfp8_ptr_type_node = build_pointer_type (aarch64_mfp8_type_node); +} + /* Initialize the backend types that support the user-visible __fp16 type, also initialize a pointer to that type, to be used when forming HFAs. */ @@ -2228,6 +2246,8 @@ aarch64_general_init_builtins (void) { aarch64_init_fpsr_fpcr_builtins (); + aarch64_init_fp8_types (); + aarch64_init_fp16_types (); aarch64_init_bf16_types (); diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 4131d2fe65b0..e7bb3278a27e 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -22507,6 +22507,10 @@ aarch64_mangle_type (const_tree type) return "Dh"; } + /* Modal 8 bit floating point types. */ + if (TYPE_MAIN_VARIANT (type) == aarch64_mfp8_type_node) +return "u6__m
[gcc r15-3994] [PATCH] RISC-V/libgcc: Fix incorrect and missing .cfi_offset for __riscv_save_[0-3] on RV32.
https://gcc.gnu.org/g:97fd777248f3c22f6baa5a25f25f7dd510ca5e63 commit r15-3994-g97fd777248f3c22f6baa5a25f25f7dd510ca5e63 Author: Tsung Chun Lin Date: Tue Oct 1 09:10:29 2024 -0600 [PATCH] RISC-V/libgcc: Fix incorrect and missing .cfi_offset for __riscv_save_[0-3] on RV32. 0001-RISC-V-libgcc-Fix-incorrect-and-missing-.cfi_offset-.patch From 06a370a0a2329dd4da0ffcab7c35ea7df2353baf Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Tue, 1 Oct 2024 14:42:56 +0800 Subject: [PATCH] RISC-V/libgcc: Fix incorrect and missing .cfi_offset for __riscv_save_[0-3] on RV32. libgcc/ChangeLog: * config/riscv/save-restore.S: Fix .cfi_offset for __riscv_save_[0-3] on RV32. Diff: --- libgcc/config/riscv/save-restore.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libgcc/config/riscv/save-restore.S b/libgcc/config/riscv/save-restore.S index 8a4391e1a978..30d06cc6e5bb 100644 --- a/libgcc/config/riscv/save-restore.S +++ b/libgcc/config/riscv/save-restore.S @@ -421,8 +421,9 @@ FUNC_BEGIN (__riscv_save_0) addi sp, sp, -16 .cfi_def_cfa_offset 16 sw s2, 0(sp) + .cfi_offset 18, -16 sw s1, 4(sp) - .cfi_offset 9, -16 + .cfi_offset 9, -12 sw s0, 8(sp) .cfi_offset 8, -8 sw ra, 12(sp)
[gcc r15-3985] range-cache: Fix ranger ICE if number of bbs increases [PR116899]
https://gcc.gnu.org/g:de25f1729d212c11d6e2955130f4eb1d272b5ce7 commit r15-3985-gde25f1729d212c11d6e2955130f4eb1d272b5ce7 Author: Jakub Jelinek Date: Tue Oct 1 09:52:20 2024 +0200 range-cache: Fix ranger ICE if number of bbs increases [PR116899] Ranger cache during initialization reserves number of basic block slots in the m_workback vector (in an inefficient way by doing create (0) and safe_grow_cleared (n) and truncate (0) rather than say create (n) or reserve (n) after create). The problem is that some passes split bbs and/or create new basic blocks and so when one is unlucky, the quick_push into that vector can ICE. The following patch replaces those 4 quick_push calls with safe_push. I've also gathered some statistics from compiling 63 gcc sources (picked those that dependent on gimple-range-cache.h just because I had to rebuild them once for the instrumentation), and that showed that in 81% of cases nothing has been pushed into the vector at all (and note, not everything was small, there were even cases with 1+ basic blocks), another 18.5% of cases had just 1-4 elements in the vector at most, 0.08% had 5-8 and 19 out of 305386 cases had at most 9-11 elements, nothing more. So, IMHO reserving number of basic block in the vector is a waste of compile time memory and with the safe_push calls, the patch just initializes the vector to vNULL. 2024-10-01 Jakub Jelinek PR middle-end/116899 * gimple-range-cache.cc (ranger_cache::ranger_cache): Set m_workback to vNULL instead of creating it, growing and then truncating. (ranger_cache::fill_block_cache): Use safe_push rather than quick_push on m_workback. (ranger_cache::range_from_dom): Likewise. * gcc.dg/bitint-111.c: New test. Diff: --- gcc/gimple-range-cache.cc | 12 +--- gcc/testsuite/gcc.dg/bitint-111.c | 16 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index c0b8916e85af..035076be5d87 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -997,9 +997,7 @@ update_list::pop () ranger_cache::ranger_cache (int not_executable_flag, bool use_imm_uses) { - m_workback.create (0); - m_workback.safe_grow_cleared (last_basic_block_for_fn (cfun)); - m_workback.truncate (0); + m_workback = vNULL; m_temporal = new temporal_cache; // If DOM info is available, spawn an oracle as well. @@ -1560,7 +1558,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb) // Visit each block back to the DEF. Initialize each one to UNDEFINED. // m_visited at the end will contain all the blocks that we needed to set // the range_on_entry cache for. - m_workback.quick_push (bb); + m_workback.safe_push (bb); undefined.set_undefined (); m_on_entry.set_bb_range (name, bb, undefined); gcc_checking_assert (m_update->empty_p ()); @@ -1634,7 +1632,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb) // the list. gcc_checking_assert (!m_on_entry.bb_range_p (name, pred)); m_on_entry.set_bb_range (name, pred, undefined); - m_workback.quick_push (pred); + m_workback.safe_push (pred); } } @@ -1729,7 +1727,7 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb, // This block has an outgoing range. if (gori ().has_edge_range_p (name, bb)) - m_workback.quick_push (prev_bb); + m_workback.safe_push (prev_bb); else { // Normally join blocks don't carry any new range information on @@ -1753,7 +1751,7 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb, break; } if (all_dom) - m_workback.quick_push (prev_bb); + m_workback.safe_push (prev_bb); } } diff --git a/gcc/testsuite/gcc.dg/bitint-111.c b/gcc/testsuite/gcc.dg/bitint-111.c new file mode 100644 index ..3cc23684c844 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-111.c @@ -0,0 +1,16 @@ +/* PR middle-end/116899 */ +/* { dg-do compile { target bitint575 } } */ +/* { dg-options "-O2" } */ + +float f; +_BitInt(255) b; + +void +foo (signed char c) +{ + for (;;) +{ + c %= (unsigned _BitInt(512)) 0; /* { dg-warning "division by zero" } */ + f /= b >= c; +} +}
[gcc/devel/nothrow-detection] Added code for inserting regions
https://gcc.gnu.org/g:1a736e25705f0b15ee4bd1994fe587bb809c7bcb commit 1a736e25705f0b15ee4bd1994fe587bb809c7bcb Author: Pranil Dey Date: Tue Oct 1 19:50:42 2024 +0530 Added code for inserting regions Diff: --- gcc/tree-eh.cc | 51 +-- gcc/tree-eh.h | 2 ++ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 37eb6081eca9..3723b6672bf2 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2283,7 +2283,7 @@ same_or_derived_type (tree t1, tree t2) t2 = TYPE_MAIN_VARIANT (t2); if (t1 == t2) return true; - while ((TREE_CODE (t1) == POINTER_TYPE || TREE_CODE (t1) == REFERENCE_TYPE) + while ( (TREE_CODE (t1) == POINTER_TYPE || TREE_CODE (t1) == REFERENCE_TYPE) && TREE_CODE (t1) == TREE_CODE (t2)) { t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1)); @@ -2326,6 +2326,29 @@ bool match_lp (eh_landing_pad lp, vec *exception_types) { return false; } +void unlink_eh_region (eh_region region, eh_region prev_region) { +if (region->outer && region->outer->inner == region) { +region->outer->inner = region->next_peer; +} +if (prev_region && prev_region->next_peer == region) { +prev_region->next_peer = region->next_peer; +} +region->next_peer = NULL; +region->outer = NULL; +} + +void reinsert_eh_region (eh_region region, eh_landing_pad lp) { +eh_region new_outer = lp->region->outer; +region->outer = new_outer; +if (new_outer) { +region->next_peer = new_outer->inner; +new_outer->inner = region; +} else { +region->next_peer = cfun->eh->region_tree; +cfun->eh->region_tree = region; +} +} + // Function to update landing pad in throw_stmt_table for a given statement void update_stmt_eh_region (gimple *stmt) { auto_vec exception_types; @@ -2344,6 +2367,7 @@ void update_stmt_eh_region (gimple *stmt) { } eh_region region = lp->region; +eh_region prev_region = NULL; // Walk up the region tree while (region) { @@ -2354,6 +2378,9 @@ void update_stmt_eh_region (gimple *stmt) { gimple_resx_set_region (resx_stmt, region->index); } else *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; + +unlink_eh_region (region, prev_region); +reinsert_eh_region (region, lp); return; case ERT_TRY: @@ -2363,6 +2390,9 @@ void update_stmt_eh_region (gimple *stmt) { gimple_resx_set_region (resx_stmt, region->index); } else *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; + + unlink_eh_region (region, prev_region); + reinsert_eh_region (region, lp); return; } break; @@ -2380,12 +2410,13 @@ void update_stmt_eh_region (gimple *stmt) { default: break; } +prev_region = region; region = region->outer; } if (gimple_code (stmt) == GIMPLE_RESX){ gresx *resx_stmt = as_a (stmt); - gimple_resx_set_region (resx_stmt, 0); + gimple_resx_set_region (resx_stmt, region->index); } else remove_stmt_from_eh_lp_fn (cfun, stmt); } @@ -3097,7 +3128,7 @@ void extract_types_for_resx (gimple *resx_stmt, vec *ret_vector) { extract_types_for_call (as_a (last_stmt), ret_vector); continue; } - else if (gimple_code(last_stmt) == GIMPLE_RESX){ + else if (gimple_code (last_stmt) == GIMPLE_RESX){ // Recursively processing resx extract_types_for_resx (last_stmt, ret_vector); continue; @@ -3119,26 +3150,26 @@ void extract_fun_resx_types (function *fun, vec *ret_vector) { bb->aux = (void*)1; gsi = gsi_last_bb (bb); gimple *stmt = gsi_stmt (gsi); - vec *ret_vector; + vec *resx_types; if (stmt_can_throw_external (fun, stmt)){ if (gimple_code (stmt) == GIMPLE_RESX){ - extract_types_for_resx (stmt, ret_vector); + extract_types_for_resx (stmt, resx_types); } else if (gimple_code (stmt) == GIMPLE_CALL){ - extract_types_for_call (as_a (stmt), ret_vector); + extract_types_for_call (as_a (stmt), resx_types); } } - for (unsigned i = 0;ilength ();++i){ - tree type = (*ret_vector)[i]; + for (unsigned i = 0;ilength ();++i){ + tree type = (*resx_types)[i]; types->add (type); } } - for (auto it = types->begin(); it != types->end(); ++it) {
[gcc r15-3986] tree-optimization/116906 - unsafe PRE with never executed edges
https://gcc.gnu.org/g:3e1bd6470e4deba1a3ad14621037098311ad1350 commit r15-3986-g3e1bd6470e4deba1a3ad14621037098311ad1350 Author: Richard Biener Date: Tue Oct 1 10:37:16 2024 +0200 tree-optimization/116906 - unsafe PRE with never executed edges When we're computing ANTIC for PRE we treat edges to not yet visited blocks as having a maximum ANTIC solution to get at an optimistic solution in the iteration. That assumes the edges visted eventually execute. This is a wrong assumption that can lead to wrong code (and not only non-optimality) when possibly trapping expressions are involved as the testcases in the PR show. The following mitigates this by pruning trapping expressions from ANTIC computed when maximum sets are involved. PR tree-optimization/116906 * tree-ssa-pre.cc (prune_clobbered_mems): Add clean_traps argument. (compute_antic_aux): Direct prune_clobbered_mems to prune all traps when any MAX solution was involved in the ANTIC computation. (compute_partial_antic_aux): Adjust. * gcc.dg/pr116906-1.c: New testcase. * gcc.dg/pr116906-2.c: Likewise. Diff: --- gcc/testsuite/gcc.dg/pr116906-1.c | 43 +++ gcc/testsuite/gcc.dg/pr116906-2.c | 40 gcc/tree-ssa-pre.cc | 16 +-- 3 files changed, 93 insertions(+), 6 deletions(-) diff --git a/gcc/testsuite/gcc.dg/pr116906-1.c b/gcc/testsuite/gcc.dg/pr116906-1.c new file mode 100644 index ..27b1fdae02bf --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr116906-1.c @@ -0,0 +1,43 @@ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ +/* { dg-options "-O2" } */ + +#include +#include +#include +#include + +int a = 1, b = 0; + +uint64_t safe_mod(uint64_t a, uint64_t b) +{ +if (b == 0) return a; +else return a % b; +} + +int __attribute__((noipa)) +f(uint64_t p) +{ +int c = 0; +j: +b = safe_mod( +(c = ((a &= (0 < p)) && 1), 1), p); +if (!c) +goto j; +return 0; +} + +void do_exit (int i) +{ + exit (0); +} + +int main() +{ + struct sigaction s; + sigemptyset (&s.sa_mask); + s.sa_handler = do_exit; + s.sa_flags = 0; + sigaction (SIGALRM, &s, NULL); + alarm (1); + f(b); +} diff --git a/gcc/testsuite/gcc.dg/pr116906-2.c b/gcc/testsuite/gcc.dg/pr116906-2.c new file mode 100644 index ..3478771678ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr116906-2.c @@ -0,0 +1,40 @@ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ +/* { dg-options "-O2 -fno-tree-ch" } */ + +#include +#include +#include + +int x; + +void __attribute__((noipa)) +foo (int *p, unsigned n) +{ + unsigned i = 0; + do +{ + if (i == n) +break; + if (p) +x = *p; + i += 2; +} + while (1); + x = *p; +} + +void do_exit (int i) +{ + exit (0); +} + +int main() +{ + struct sigaction s; + sigemptyset (&s.sa_mask); + s.sa_handler = do_exit; + s.sa_flags = 0; + sigaction (SIGALRM, &s, NULL); + alarm (1); + foo ((int *)0, 1); +} diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc index 6c0436b8b152..13f2c8a5420d 100644 --- a/gcc/tree-ssa-pre.cc +++ b/gcc/tree-ssa-pre.cc @@ -2008,10 +2008,11 @@ clean (bitmap_set_t set1, bitmap_set_t set2 = NULL) } /* Clean the set of expressions that are no longer valid in SET because - they are clobbered in BLOCK or because they trap and may not be executed. */ + they are clobbered in BLOCK or because they trap and may not be executed. + When CLEAN_TRAPS is true remove all possibly trapping expressions. */ static void -prune_clobbered_mems (bitmap_set_t set, basic_block block) +prune_clobbered_mems (bitmap_set_t set, basic_block block, bool clean_traps) { bitmap_iterator bi; unsigned i; @@ -2049,7 +2050,7 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block) a possible exit point. ??? This is overly conservative if we translate AVAIL_OUT as the available expression might be after the exit point. */ - if (BB_MAY_NOTRETURN (block) + if ((BB_MAY_NOTRETURN (block) || clean_traps) && vn_reference_may_trap (ref)) to_remove = i; } @@ -2060,7 +2061,7 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block) a possible exit point. ??? This is overly conservative if we translate AVAIL_OUT as the available expression might be after the exit point. */ - if (BB_MAY_NOTRETURN (block) + if ((BB_MAY_NOTRETURN (block) || clean_traps) && vn_nary_may_trap (nary)) to_remove = i; } @@ -2114,6 +2115,8 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) bool was_visited = BB_VISITED (block); bool changed = ! BB_VISITED (block); + bool any_max_on_edge = fa
[gcc r15-3988] tree-optimization/116902 - vectorizer load hosting breaks UID order #2
https://gcc.gnu.org/g:27ddda8b4cb51739e841053c29d9b5f503467e99 commit r15-3988-g27ddda8b4cb51739e841053c29d9b5f503467e99 Author: Richard Biener Date: Tue Oct 1 13:35:58 2024 +0200 tree-optimization/116902 - vectorizer load hosting breaks UID order #2 This is another case of load hoisting breaking UID order in the preheader, this time between two hoistings. The easiest way out is to do what we do for the main stmt - copy instead of move. PR tree-optimization/116902 PR tree-optimization/116842 * tree-vect-stmts.cc (sort_after_uid): Remove again. (hoist_defs_of_uses): Copy defs instead of hoisting them so we can zero their UID. (vectorizable_load): Separate analysis and transform call, do transform on the stmt copy. * g++.dg/torture/pr116902.C: New testcase. Diff: --- gcc/testsuite/g++.dg/torture/pr116902.C | 20 gcc/tree-vect-stmts.cc | 54 +++-- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/gcc/testsuite/g++.dg/torture/pr116902.C b/gcc/testsuite/g++.dg/torture/pr116902.C new file mode 100644 index ..cf195c8ac024 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr116902.C @@ -0,0 +1,20 @@ +// { dg-do compile } +// { dg-additional-options "-ftree-vectorize" } + +template +inline const _Tp& +min(const _Tp& __a, const _Tp& __b) +{ + if (__b < __a) +return __b; + return __a; +} + +unsigned a; +void i(long b, char c[][4], long d[][4]) { + for (char e; e; e++) +for (char f = 0; f < 021; f = b) + for (signed char g; g < 7; g += ~0) +for (bool h = 0; h < bool(d[f][f]); h = 1) + a = c[2][1] - min(c[1][f + 1], c[2][f + 2]); +} diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index b880f0507158..584be52f4237 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -9788,20 +9788,6 @@ permute_vec_elements (vec_info *vinfo, return data_ref; } -/* Comparator for qsort, sorting after GIMPLE UID. */ - -static int -sort_after_uid (const void *a_, const void *b_) -{ - const gimple *a = *(const gimple * const *)a_; - const gimple *b = *(const gimple * const *)b_; - if (gimple_uid (a) < gimple_uid (b)) -return -1; - else if (gimple_uid (a) > gimple_uid (b)) -return 1; - return 0; -} - /* Hoist the definitions of all SSA uses on STMT_INFO out of the loop LOOP, inserting them on the loops preheader edge. Returns true if we were successful in doing so (and thus STMT_INFO can be moved then), @@ -9809,15 +9795,15 @@ sort_after_uid (const void *a_, const void *b_) definitions of all SSA uses, it would be false when we are costing. */ static bool -hoist_defs_of_uses (stmt_vec_info stmt_info, class loop *loop, bool hoist_p) +hoist_defs_of_uses (gimple *stmt, class loop *loop, bool hoist_p) { ssa_op_iter i; - tree op; - auto_vec to_hoist; + use_operand_p use_p; + auto_vec to_hoist; - FOR_EACH_SSA_TREE_OPERAND (op, stmt_info->stmt, i, SSA_OP_USE) + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, i, SSA_OP_USE) { - gimple *def_stmt = SSA_NAME_DEF_STMT (op); + gimple *def_stmt = SSA_NAME_DEF_STMT (USE_FROM_PTR (use_p)); if (!gimple_nop_p (def_stmt) && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))) { @@ -9827,7 +9813,9 @@ hoist_defs_of_uses (stmt_vec_info stmt_info, class loop *loop, bool hoist_p) dependencies within them. */ tree op2; ssa_op_iter i2; - if (gimple_code (def_stmt) == GIMPLE_PHI) + if (gimple_code (def_stmt) == GIMPLE_PHI + || (single_ssa_def_operand (def_stmt, SSA_OP_DEF) + == NULL_DEF_OPERAND_P)) return false; FOR_EACH_SSA_TREE_OPERAND (op2, def_stmt, i2, SSA_OP_USE) { @@ -9836,7 +9824,7 @@ hoist_defs_of_uses (stmt_vec_info stmt_info, class loop *loop, bool hoist_p) && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt2))) return false; } - to_hoist.safe_push (def_stmt); + to_hoist.safe_push (use_p); } } @@ -9846,14 +9834,21 @@ hoist_defs_of_uses (stmt_vec_info stmt_info, class loop *loop, bool hoist_p) if (!hoist_p) return true; - /* Preserve UID order, otherwise we break dominance checks. */ - to_hoist.qsort (sort_after_uid); - - for (gimple *def_stmt : to_hoist) + /* Instead of moving defs we copy them so we can zero their UID to not + confuse dominance queries in the preheader. */ + gimple_stmt_iterator gsi = gsi_for_stmt (stmt); + for (use_operand_p use_p : to_hoist) { - gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt); - gsi_remove (&gsi, false); - gsi_insert_on_edge_immediate (loop_preheader_edge (loop), def_stmt); + gimple *def_stmt = SSA_NAME_DEF_STMT (USE_FROM_PTR (use_p)); + gimple *copy = gimple_copy (def_stmt);
[gcc r15-3995] Fix wrong code out of NRV + RSO + inlining
https://gcc.gnu.org/g:be2f7a1871ae7a256f34393eeba583ff575cb7e8 commit r15-3995-gbe2f7a1871ae7a256f34393eeba583ff575cb7e8 Author: Eric Botcazou Date: Tue Oct 1 17:54:00 2024 +0200 Fix wrong code out of NRV + RSO + inlining The testcase is miscompiled with -O -flto beccause the three optimizations NRV + RSO + inlining are applied to the same call: when the LHS of the call is marked write-only before inlining, it will keep the mark after inlining although it may be read in GIMPLE from that point on. The fix is to apply the removal of the store, that would have been applied later if the call was not inlined, right before inlining, which will prevent the problematic references to the LHS from being generated during inlining. gcc/ * tree-inline.cc (expand_call_inline): Remove the store to the return slot if it is a global variable that is only written to. gcc/testsuite/ * gnat.dg/lto28.adb: New test. * gnat.dg/lto28_pkg1.ads: New helper. * gnat.dg/lto28_pkg2.ads: Likewise. * gnat.dg/lto28_pkg2.adb: Likewise. * gnat.dg/lto28_pkg3.ads: Likewise. Diff: --- gcc/testsuite/gnat.dg/lto28.adb | 9 + gcc/testsuite/gnat.dg/lto28_pkg1.ads | 5 + gcc/testsuite/gnat.dg/lto28_pkg2.adb | 10 ++ gcc/testsuite/gnat.dg/lto28_pkg2.ads | 11 +++ gcc/testsuite/gnat.dg/lto28_pkg3.ads | 19 +++ gcc/tree-inline.cc | 16 +++- 6 files changed, 69 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/gnat.dg/lto28.adb b/gcc/testsuite/gnat.dg/lto28.adb new file mode 100644 index ..f5f1804af866 --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto28.adb @@ -0,0 +1,9 @@ +-- { dg-do run } +-- { dg-options "-O -flto" { target lto } } + +with Lto28_Pkg1; + +procedure Lto28 is +begin + null; +end; diff --git a/gcc/testsuite/gnat.dg/lto28_pkg1.ads b/gcc/testsuite/gnat.dg/lto28_pkg1.ads new file mode 100644 index ..8205cdae7315 --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto28_pkg1.ads @@ -0,0 +1,5 @@ +with Lto28_Pkg2; + +package Lto28_Pkg1 is + package I is new Lto28_Pkg2.G; +end Lto28_Pkg1; diff --git a/gcc/testsuite/gnat.dg/lto28_pkg2.adb b/gcc/testsuite/gnat.dg/lto28_pkg2.adb new file mode 100644 index ..f592d119c40f --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto28_pkg2.adb @@ -0,0 +1,10 @@ +package body Lto28_Pkg2 is + + function F return Lto28_Pkg3.Q_Rec is + begin + return Result : Lto28_Pkg3.Q_Rec := Lto28_Pkg3.Default_Q_Rec do + Result.A := 1.0; + end return; + end; + +end Lto28_Pkg2; diff --git a/gcc/testsuite/gnat.dg/lto28_pkg2.ads b/gcc/testsuite/gnat.dg/lto28_pkg2.ads new file mode 100644 index ..ba2d0ae5781c --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto28_pkg2.ads @@ -0,0 +1,11 @@ +with Lto28_Pkg3; + +package Lto28_Pkg2 is + + function F return Lto28_Pkg3.Q_Rec; + + generic + Q_Conf : Lto28_Pkg3.Q_Rec := F; + package G is end; + +end Lto28_Pkg2; diff --git a/gcc/testsuite/gnat.dg/lto28_pkg3.ads b/gcc/testsuite/gnat.dg/lto28_pkg3.ads new file mode 100644 index ..026ffb9f97c4 --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto28_pkg3.ads @@ -0,0 +1,19 @@ +package Lto28_Pkg3 is + + type Discr_Type is (P, Q); + + type Rec (Discr : Discr_Type) is record + case Discr is + when Q => +A : Duration := 0.0; +B : Duration := 0.0; + when P => +null; + end case; + end record; + + subtype Q_Rec is Rec (Q); + + Default_Q_Rec : constant Q_Rec := (Discr => Q, others => <>); + +end Lto28_Pkg3; diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc index f31a34ac4105..037fd1e946ae 100644 --- a/gcc/tree-inline.cc +++ b/gcc/tree-inline.cc @@ -5130,9 +5130,23 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id, if (DECL_P (modify_dest)) suppress_warning (modify_dest, OPT_Wuninitialized); + /* If we have a return slot, we can assign it the result directly, +except in the case where it is a global variable that is only +written to because, the callee being permitted to read or take +the address of its DECL_RESULT, this could invalidate the flag +on the global variable; instead we preventively remove the store, +which would have happened later if the call was not inlined. */ if (gimple_call_return_slot_opt_p (call_stmt)) { - return_slot = modify_dest; + tree base = get_base_address (modify_dest); + + if (VAR_P (base) + && (TREE_STATIC (base) || DECL_EXTERNAL (base)) + && varpool_node::get (base)->writeonly) + return_slot = NULL; + else + return_slot = modify_dest; + modify_dest = NULL; } }
[gcc r15-3990] PR modula2/116918 -fswig correct syntax
https://gcc.gnu.org/g:fda30a3c8a7c6b06f02be40e3fd0740f893a1b4f commit r15-3990-gfda30a3c8a7c6b06f02be40e3fd0740f893a1b4f Author: Gaius Mulley Date: Tue Oct 1 14:26:31 2024 +0100 PR modula2/116918 -fswig correct syntax This patch fixes the syntax for the generated swig interface file. The % characters in fprintf require escaping. gcc/m2/ChangeLog: PR modula2/116918 * gm2-compiler/M2Swig.mod (AnnotateProcedure): Capitalize the generated comment, split comment into multiple lines and terminate the comment with ". */". (DoCheckUnbounded): Escape the % character with %%. (DoWriteFile): Ditto. Signed-off-by: Gaius Mulley Diff: --- gcc/m2/gm2-compiler/M2Swig.mod | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/gcc/m2/gm2-compiler/M2Swig.mod b/gcc/m2/gm2-compiler/M2Swig.mod index 194abd5fb786..b7f34426adb8 100644 --- a/gcc/m2/gm2-compiler/M2Swig.mod +++ b/gcc/m2/gm2-compiler/M2Swig.mod @@ -685,7 +685,7 @@ VAR son, p, i: CARDINAL ; needComma: BOOLEAN ; BEGIN - fprintf0(f, '/* parameter: ') ; + fprintf0(f, '/* Parameter: ') ; p := NoOfParam(sym) ; i := 1 ; needComma := FALSE ; @@ -695,14 +695,14 @@ BEGIN THEN IF needComma THEN -fprintf0(f, ', ') +fprintf0(f, ',\n ') END ; CalculateVarDirective(sym, son, TRUE) ; needComma := TRUE END ; INC(i) END ; - fprintf0(f, ' */\n\n') + fprintf0(f, '. */\n\n') END AnnotateProcedure ; @@ -879,9 +879,9 @@ BEGIN IF NOT includedArray THEN includedArray := TRUE ; -fprintf0(f, '%include "carrays.i"\n') +fprintf0(f, '%%include "carrays.i"\n') END ; - fprintf0(f, '%') ; + fprintf0(f, '%%') ; fprintf0(f, 'apply (char *STRING, int LENGTH) { (') ; DoUnbounded(sym) ; fprintf0(f, ') };\n') ; @@ -908,12 +908,12 @@ VAR BEGIN mainModule := sym ; n := GetSymName(sym) ; - fprintf0(f, '/* automatically generated by gm2 -fswig */\n') ; - fprintf0(f, '%') ; + fprintf0(f, '/* Automatically generated by gm2 -fswig. */\n') ; + fprintf0(f, '%%') ; fprintf1(f, 'module %a\n\n', n) ; - fprintf0(f, '%') ; + fprintf0(f, '%%') ; fprintf1(f, 'include exception.i\n\n', n) ; - fprintf0(f, '%') ; + fprintf0(f, '%%') ; fprintf0(f, 'exception {\n') ; fprintf0(f, ' try {\n') ; fprintf0(f, ' $action\n') ; @@ -922,9 +922,9 @@ BEGIN fprintf0(f, ' }\n') ; fprintf0(f, '}\n\n') ; ForeachItemInListDo(Done, DoCheckUnbounded) ; - fprintf0(f, '\n%{\n') ; + fprintf0(f, '\n%%{\n') ; ForeachItemInListDo(Done, DoCheckExported) ; - fprintf0(f, '%}\n\n') ; + fprintf0(f, '%%}\n\n') ; ForeachItemInListDo(Done, DoCheckExported) END DoWriteFile ;
[gcc r15-3992] phi-opt: Improve factor heurstic with constants and conversions from bool [PR116890]
https://gcc.gnu.org/g:698e0ec89bc0960e074d208bffe47f5addd9 commit r15-3992-g698e0ec89bc0960e074d208bffe47f5addd9 Author: Andrew Pinski Date: Mon Sep 30 16:44:44 2024 + phi-opt: Improve factor heurstic with constants and conversions from bool [PR116890] Take: ``` if (t_3(D) != 0) goto ; else goto ; _8 = c_4(D) != 0; _9 = (int) _8; # e_2 = PHI <_9(3), 0(2)> ``` We should factor out the conversion here as that will allow a simplfication to `(t_3 != 0) & (c_4 != 0)`. Unlike most other types; `a ? b : CST` will simplify for boolean result type to either `a | b` or `a & b` so allowing this conversion for all operations will be always profitable. Bootstrapped and tested on x86_64-linux-gnu with no regressions. Note on the phi-opt-7.c testcase change, we are now able to optimize this and remove the if due to the factoring out now so this is an improvement. PR tree-optimization/116890 gcc/ChangeLog: * tree-ssa-phiopt.cc (factor_out_conditional_operation): Conversions from bool is also should be considered as wanting to happen. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/phi-opt-7.c: Update testcase for no ifs left. * gcc.dg/tree-ssa/phi-opt-42.c: New test. * gcc.dg/tree-ssa/phi-opt-43.c: New test. Signed-off-by: Andrew Pinski Diff: --- gcc/testsuite/gcc.dg/tree-ssa/phi-opt-42.c | 19 +++ gcc/testsuite/gcc.dg/tree-ssa/phi-opt-43.c | 19 +++ gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c | 6 +++--- gcc/tree-ssa-phiopt.cc | 10 +- 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-42.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-42.c new file mode 100644 index ..62556945159c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-42.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +/* PR tree-optimization/116890 */ + +int f(int a, int b, int c) +{ + int x; + if (c) x = a == 0; + else x = 0; + return x; +} + + +/* The if should have been removed as the the conversion from bool to int should have been factored out. */ +/* { dg-final { scan-tree-dump-not "if" "optimized" } }*/ +/* { dg-final { scan-tree-dump-times "\[^\r\n\]*_\[0-9\]* = a_\[0-9\]*.D. == 0" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\[^\r\n\]*_\[0-9\]* = c_\[0-9\]*.D. != 0" 1 "optimized" } } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-43.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-43.c new file mode 100644 index ..1d16f283f27b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-43.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +/* PR tree-optimization/116890 */ + +int f(_Bool a, _Bool b, int c) +{ + int x; + if (c) x = a & b; + else x = 0; + return x; +} + + +/* The if should have been removed as the the conversion from bool to int should have been factored out. */ +/* { dg-final { scan-tree-dump-not "if" "optimized" } }*/ +/* { dg-final { scan-tree-dump-times "\[^\r\n\]*_\[0-9\]* = a_\[0-9\]*.D. & b_\[0-9\]*.D." 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\[^\r\n\]*_\[0-9\]* = c_\[0-9\]*.D. != 0" 1 "optimized" } } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c index 51e1f6dfa755..3ee43e55692e 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c @@ -15,8 +15,8 @@ int f(int t, int c) return g(d,e); } -/* There should be one ifs as one of them should be changed into - a conditional and the other should be there still. */ -/* { dg-final { scan-tree-dump-times "if" 1 "optimized" } }*/ +/* There should be no ifs as this is converted into `(t != 0) & (c != 0)`. +/* { dg-final { scan-tree-dump-not "if" "optimized" } }*/ /* { dg-final { scan-tree-dump-times "\[^\r\n\]*_\[0-9\]* = c_\[0-9\]*.D. != 0" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\[^\r\n\]*_\[0-9\]* = t_\[0-9\]*.D. != 0" 1 "optimized" } } */ diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc index d43832b390ba..bd7f9607eb9a 100644 --- a/gcc/tree-ssa-phiopt.cc +++ b/gcc/tree-ssa-phiopt.cc @@ -345,9 +345,17 @@ factor_out_conditional_operation (edge e0, edge e1, gphi *phi, if (gassign *assign = dyn_cast (stmt)) { tree lhs = gimple_assign_lhs (assign); + tree lhst = TREE_TYPE (lhs); enum tree_code ass_code = gimple_assign_rhs_code (assign); - if (ass_code != MAX_EXPR && ass_code != MIN_EXPR) + if (ass_code != MAX_EXPR && ass_code != MIN_EXPR +
[gcc r15-3999] AVR: avr.cc - Drop a superfluous sub-condition in avr_out_compare.
https://gcc.gnu.org/g:f72b1a44ff582041b02d5abe0a6c8556057e6183 commit r15-3999-gf72b1a44ff582041b02d5abe0a6c8556057e6183 Author: Georg-Johann Lay Date: Tue Oct 1 20:36:22 2024 +0200 AVR: avr.cc - Drop a superfluous sub-condition in avr_out_compare. In avr.cc::avr_out_compare() there is this condition: if (n_bytes == 4 && eqne_p && AVR_HAVE_ADIW && REGNO (xreg) >= REG_22 && (xval == const0_rtx || (IN_RANGE (avr_int16 (xval, 2), 0, 63) && eqne_p && reg_unused_after (insn, xreg where the 2nd sub-expression "&& eqne_p" is superfluous. gcc/ * config/avr/avr.cc (avr_out_compare): Drop superfluous sub-condition. Diff: --- gcc/config/avr/avr.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index c0bf1320fdd9..92013c3845db 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -6142,7 +6142,6 @@ avr_out_compare (rtx_insn *insn, rtx *xop, int *plen) && REGNO (xreg) >= REG_22 && (xval == const0_rtx || (IN_RANGE (avr_int16 (xval, 2), 0, 63) - && eqne_p && reg_unused_after (insn, xreg { xop[2] = avr_word (xval, 2);
[gcc r14-10726] c++: fix -Wdangling-reference false positive [PR115987]
https://gcc.gnu.org/g:7232bc180632f0ccce260bd33598faf6297d4fe6 commit r14-10726-g7232bc180632f0ccce260bd33598faf6297d4fe6 Author: Marek Polacek Date: Wed Jul 31 17:33:55 2024 -0400 c++: fix -Wdangling-reference false positive [PR115987] This fixes another false positive. When a function is taking a temporary of scalar type that couldn't be bound to the return type of the function, don't warn, such a program would be ill-formed. Thanks to Jonathan for reporting the problem. PR c++/115987 gcc/cp/ChangeLog: * call.cc (do_warn_dangling_reference): Don't consider a temporary with a scalar type that cannot bind to the return type. gcc/testsuite/ChangeLog: * g++.dg/ext/attr-no-dangling6.C: Adjust. * g++.dg/ext/attr-no-dangling7.C: Likewise. * g++.dg/warn/Wdangling-reference22.C: New test. Diff: --- gcc/cp/call.cc| 14 -- gcc/testsuite/g++.dg/ext/attr-no-dangling6.C | 22 +++--- gcc/testsuite/g++.dg/ext/attr-no-dangling7.C | 8 gcc/testsuite/g++.dg/warn/Wdangling-reference22.C | 19 +++ 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 492d17b17446..a210ea5cd6ac 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -14288,8 +14288,18 @@ do_warn_dangling_reference (tree expr, bool arg_p) /* Recurse to see if the argument is a temporary. It could also be another call taking a temporary and returning it and initializing this reference parameter. */ - if (do_warn_dangling_reference (arg, /*arg_p=*/true)) - return expr; + if ((arg = do_warn_dangling_reference (arg, /*arg_p=*/true))) + { + /* If we know the temporary could not bind to the return type, + don't warn. This is for scalars only because for classes + we can't be sure we are not returning its sub-object. */ + if (SCALAR_TYPE_P (TREE_TYPE (arg)) + && TYPE_REF_P (rettype) + && !reference_related_p (TREE_TYPE (arg), +TREE_TYPE (rettype))) + continue; + return expr; + } /* Don't warn about member functions like: std::any a(...); S& s = a.emplace({0}, 0); diff --git a/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C b/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C index 235a5fd86c55..5b349e8e6827 100644 --- a/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C +++ b/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C @@ -12,26 +12,26 @@ struct SF { static constexpr bool value = false; }; template [[gnu::no_dangling(T::value)]] -const X& get (const int& i) +const X& get (const int& i, const X&) { return i == 0 ? x1 : x2; } template [[gnu::no_dangling(B)]] -const X& foo (const int& i) +const X& foo (const int& i, const X&) { return i == 0 ? x1 : x2; } [[gnu::no_dangling(val ())]] -const X& bar (const int& i) +const X& bar (const int& i, const X&) { return i == 0 ? x1 : x2; } [[gnu::no_dangling(!val ())]] -const X& baz (const int& i) +const X& baz (const int& i, const X&) { return i == 0 ? x1 : x2; } @@ -52,13 +52,13 @@ auto gety() -> Span; void test () { - [[maybe_unused]] const X& x1 = get (10); // { dg-bogus "dangling" } - [[maybe_unused]] const X& x2 = get (10); // { dg-warning "dangling" } - [[maybe_unused]] const X& x3 = foo (10); // { dg-bogus "dangling" } - [[maybe_unused]] const X& x4 = foo (10); // { dg-warning "dangling" } - [[maybe_unused]] const X& x7 = foo<> (10); // { dg-bogus "dangling" } - [[maybe_unused]] const X& x5 = bar (10); // { dg-bogus "dangling" } - [[maybe_unused]] const X& x6 = baz (10); // { dg-warning "dangling" } + [[maybe_unused]] const X& x1 = get (10, X{}); // { dg-bogus "dangling" } + [[maybe_unused]] const X& x2 = get (10, X{}); // { dg-warning "dangling" } + [[maybe_unused]] const X& x3 = foo (10, X{}); // { dg-bogus "dangling" } + [[maybe_unused]] const X& x4 = foo (10, X{}); // { dg-warning "dangling" } + [[maybe_unused]] const X& x7 = foo<> (10, X{});// { dg-bogus "dangling" } + [[maybe_unused]] const X& x5 = bar (10, X{}); // { dg-bogus "dangling" } + [[maybe_unused]] const X& x6 = baz (10, X{}); // { dg-warning "dangling" } [[maybe_unused]] const auto &b1 = geti()[0]; // { dg-bogus "dangling" } [[maybe_unused]] const auto &b2 = gety()[0]; // { dg-warning "dangling" } diff --git a/gcc/testsuite/g++.dg/ext/attr-no-dangling7.C b/gcc/testsuite/g++.dg/ext/attr-no-dangling7.C index 3c392ed409f8..a5fb809e6bdb 100644 --- a/gcc/testsuite/g++.dg/ext/attr-no-dangling7.C +++ b/gcc/testsuite/g++.dg/ext/attr-no-dangling7.C @@ -16,16 +
[gcc r14-10727] c++: -Wdangling-reference and empty class [PR115361]
https://gcc.gnu.org/g:47b205b4dcca8be98bff96ea6b6f80682c65a0b1 commit r14-10727-g47b205b4dcca8be98bff96ea6b6f80682c65a0b1 Author: Jason Merrill Date: Sun Sep 15 13:50:04 2024 +0200 c++: -Wdangling-reference and empty class [PR115361] We can't have a dangling reference to an empty class unless it's specifically to that class or one of its bases. This was giving a false positive on the _ExtractKey pattern in libstdc++ hashtable.h. This also adjusts the order of arguments to reference_related_p, which is relevant for empty classes (unlike scalars). Several of the classes in the testsuite needed to gain data members to continue to warn. PR c++/115361 gcc/cp/ChangeLog: * call.cc (do_warn_dangling_reference): Check is_empty_class. gcc/testsuite/ChangeLog: * g++.dg/ext/attr-no-dangling6.C * g++.dg/ext/attr-no-dangling7.C * g++.dg/ext/attr-no-dangling8.C * g++.dg/ext/attr-no-dangling9.C * g++.dg/warn/Wdangling-reference1.C * g++.dg/warn/Wdangling-reference2.C * g++.dg/warn/Wdangling-reference3.C: Make classes non-empty. * g++.dg/warn/Wdangling-reference23.C: New test. Diff: --- gcc/cp/call.cc| 12 +++- gcc/testsuite/g++.dg/ext/attr-no-dangling6.C | 6 +++--- gcc/testsuite/g++.dg/ext/attr-no-dangling7.C | 6 +++--- gcc/testsuite/g++.dg/ext/attr-no-dangling8.C | 2 ++ gcc/testsuite/g++.dg/ext/attr-no-dangling9.C | 1 + gcc/testsuite/g++.dg/warn/Wdangling-reference1.C | 1 + gcc/testsuite/g++.dg/warn/Wdangling-reference2.C | 2 +- gcc/testsuite/g++.dg/warn/Wdangling-reference23.C | 14 ++ gcc/testsuite/g++.dg/warn/Wdangling-reference3.C | 1 + 9 files changed, 33 insertions(+), 12 deletions(-) diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index a210ea5cd6ac..423285caada4 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -14291,12 +14291,14 @@ do_warn_dangling_reference (tree expr, bool arg_p) if ((arg = do_warn_dangling_reference (arg, /*arg_p=*/true))) { /* If we know the temporary could not bind to the return type, - don't warn. This is for scalars only because for classes - we can't be sure we are not returning its sub-object. */ - if (SCALAR_TYPE_P (TREE_TYPE (arg)) + don't warn. This is for scalars and empty classes only + because for other classes we can't be sure we are not + returning its sub-object. */ + if ((SCALAR_TYPE_P (TREE_TYPE (arg)) +|| is_empty_class (TREE_TYPE (arg))) && TYPE_REF_P (rettype) - && !reference_related_p (TREE_TYPE (arg), -TREE_TYPE (rettype))) + && !reference_related_p (TREE_TYPE (rettype), +TREE_TYPE (arg))) continue; return expr; } diff --git a/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C b/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C index 5b349e8e6827..1fc426d20d3d 100644 --- a/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C +++ b/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C @@ -2,9 +2,9 @@ // { dg-do compile { target c++20 } } // { dg-options "-Wdangling-reference" } -class X { }; -const X x1; -const X x2; +class X { int i; }; +const X x1 {}; +const X x2 {}; constexpr bool val () { return true; } struct ST { static constexpr bool value = true; }; diff --git a/gcc/testsuite/g++.dg/ext/attr-no-dangling7.C b/gcc/testsuite/g++.dg/ext/attr-no-dangling7.C index a5fb809e6bdb..04c6badf0b6f 100644 --- a/gcc/testsuite/g++.dg/ext/attr-no-dangling7.C +++ b/gcc/testsuite/g++.dg/ext/attr-no-dangling7.C @@ -2,9 +2,9 @@ // { dg-do compile { target c++20 } } // { dg-options "-Wdangling-reference" } -class X { }; -const X x1; -const X x2; +class X { int i; }; +const X x1 {}; +const X x2 {}; template [[gnu::no_dangling(N)]] const X& get(const int& i); // { dg-error "parameter packs not expanded" } diff --git a/gcc/testsuite/g++.dg/ext/attr-no-dangling8.C b/gcc/testsuite/g++.dg/ext/attr-no-dangling8.C index 8208d751a4bb..aa196315a38a 100644 --- a/gcc/testsuite/g++.dg/ext/attr-no-dangling8.C +++ b/gcc/testsuite/g++.dg/ext/attr-no-dangling8.C @@ -8,6 +8,7 @@ template constexpr bool is_reference_v = true; template struct [[gnu::no_dangling(is_reference_v)]] S { + int i; int &foo (const int &); }; @@ -15,6 +16,7 @@ template struct X { template struct [[gnu::no_dangling(is_reference_v && is_reference_v)]] Y { +int i; int &foo (const int &); }; }; diff --git a/gcc/testsuite/g++.dg/ext/attr-no-dangling9.C b/gcc/testsuite/g++.dg/ext/attr-no-dangling9.C index 65b4f7145a92..d7fd897de539 100644 --- a/gcc/
[gcc r14-10728] c++: don't advertise C++20 concepts in C++14
https://gcc.gnu.org/g:91417c778ae42af342c1f6e924be39616421a860 commit r14-10728-g91417c778ae42af342c1f6e924be39616421a860 Author: Jason Merrill Date: Tue Oct 1 10:58:35 2024 -0400 c++: don't advertise C++20 concepts in C++14 There have been various problems with -std=c++14 -fconcepts; let's stop defining the feature test macro in that case. gcc/c-family/ChangeLog: * c-cppbuiltin.cc (c_cpp_builtins): Don't define __cpp_concepts before C++17. Diff: --- gcc/c-family/c-cppbuiltin.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index 38f320329829..d4aadc7666b8 100644 --- a/gcc/c-family/c-cppbuiltin.cc +++ b/gcc/c-family/c-cppbuiltin.cc @@ -1093,10 +1093,10 @@ c_cpp_builtins (cpp_reader *pfile) } if (flag_concepts) { - if (cxx_dialect >= cxx20 || !flag_concepts_ts) - cpp_define (pfile, "__cpp_concepts=202002L"); - else + if (flag_concepts_ts && cxx_dialect < cxx20) cpp_define (pfile, "__cpp_concepts=201507L"); + else if (cxx_dialect > cxx14) + cpp_define (pfile, "__cpp_concepts=202002L"); } if (flag_contracts) {
[gcc r15-4000] c++: don't advertise C++20 concepts in C++14
https://gcc.gnu.org/g:1c9b440bf6768c1053101c4a473f5fc9757f52a5 commit r15-4000-g1c9b440bf6768c1053101c4a473f5fc9757f52a5 Author: Jason Merrill Date: Tue Oct 1 10:58:35 2024 -0400 c++: don't advertise C++20 concepts in C++14 There have been various problems with -std=c++14 -fconcepts; let's stop defining the feature test macro in that case. gcc/c-family/ChangeLog: * c-cppbuiltin.cc (c_cpp_builtins): Don't define __cpp_concepts before C++17. Diff: --- gcc/c-family/c-cppbuiltin.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index 73a07055a86e..b37a4c097922 100644 --- a/gcc/c-family/c-cppbuiltin.cc +++ b/gcc/c-family/c-cppbuiltin.cc @@ -1102,7 +1102,7 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__cpp_deleted_function=202403L"); cpp_define (pfile, "__cpp_variadic_friend=202403L"); } - if (flag_concepts) + if (flag_concepts && cxx_dialect > cxx14) cpp_define (pfile, "__cpp_concepts=202002L"); if (flag_contracts) {
[gcc r13-9070] c++: don't advertise C++20 concepts in C++14
https://gcc.gnu.org/g:6ae9ef1b6bd77dca063b70a54fae46a397f6230a commit r13-9070-g6ae9ef1b6bd77dca063b70a54fae46a397f6230a Author: Jason Merrill Date: Tue Oct 1 10:58:35 2024 -0400 c++: don't advertise C++20 concepts in C++14 There have been various problems with -std=c++14 -fconcepts; let's stop defining the feature test macro in that case. And don't advertise Concepts TS support when it isn't enabled. gcc/c-family/ChangeLog: * c-cppbuiltin.cc (c_cpp_builtins): Don't define __cpp_concepts before C++17. Diff: --- gcc/c-family/c-cppbuiltin.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index 5d64625fcd7a..6983e9cebb60 100644 --- a/gcc/c-family/c-cppbuiltin.cc +++ b/gcc/c-family/c-cppbuiltin.cc @@ -1083,10 +1083,10 @@ c_cpp_builtins (cpp_reader *pfile) } if (flag_concepts) { - if (cxx_dialect >= cxx20) - cpp_define (pfile, "__cpp_concepts=202002L"); - else + if (flag_concepts_ts && cxx_dialect < cxx20) cpp_define (pfile, "__cpp_concepts=201507L"); + else if (cxx_dialect > cxx14) + cpp_define (pfile, "__cpp_concepts=202002L"); } if (flag_contracts) {
[gcc r15-4005] testsuite/116654 - adjust gcc.dg/vect/costmodel/ppc/costmodel-slp-12.c
https://gcc.gnu.org/g:b56dc0a9ac403891ddad8bce1d697ed7f5c365f7 commit r15-4005-gb56dc0a9ac403891ddad8bce1d697ed7f5c365f7 Author: Richard Biener Date: Wed Oct 2 08:25:00 2024 +0200 testsuite/116654 - adjust gcc.dg/vect/costmodel/ppc/costmodel-slp-12.c As we now SLP non-grouped stores we have to adjust the expected count. PR testsuite/116654 * gcc.dg/vect/costmodel/ppc/costmodel-slp-12.c: Adjust. Diff: --- gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-12.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-12.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-12.c index 9e57cae9751d..bd080f0016f4 100644 --- a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-12.c +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-12.c @@ -117,5 +117,5 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" {target { vect_strided8 && vect_int_mult } } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" {target { vect_strided8 && vect_int_mult } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 6 "vect" {target { vect_strided8 && vect_int_mult } } } } */
[gcc r15-4006] testsuite/116654 - adjust gcc.target/powerpc/p9-vec-length-full-8.c
https://gcc.gnu.org/g:eb0698ae62fedae90e5c5cc071c8aa5c1cb2f74d commit r15-4006-geb0698ae62fedae90e5c5cc071c8aa5c1cb2f74d Author: Richard Biener Date: Wed Oct 2 08:41:30 2024 +0200 testsuite/116654 - adjust gcc.target/powerpc/p9-vec-length-full-8.c gcc.target/powerpc/p9-vec-length-full-8.c was expecting all loops to use -with-len fully masked vectorization to avoid epilogues because the loops needed peeling for gaps. With SLP we have improved things here and the loops using V2D[IF]mode no longer need peeling for gaps since the target can compose those vectors from two scalars and in turn we generate better code and not need an epilogue either (the iteration count divides by the VF). PR testsuite/116654 * gcc.target/powerpc/p9-vec-length-full-8.c: Adjust. Diff: --- gcc/testsuite/gcc.target/powerpc/p9-vec-length-full-8.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/gcc.target/powerpc/p9-vec-length-full-8.c b/gcc/testsuite/gcc.target/powerpc/p9-vec-length-full-8.c index 53fa8ebc3ff5..8b303841aea7 100644 --- a/gcc/testsuite/gcc.target/powerpc/p9-vec-length-full-8.c +++ b/gcc/testsuite/gcc.target/powerpc/p9-vec-length-full-8.c @@ -9,9 +9,10 @@ /* { dg-require-effective-target powerpc_vsx } */ /* Test for fully with length, the loop body uses vector access with length, - there should not be any epilogues. */ + there should not be any epilogues. Note for [u]int64_t and double we + can avoid peeling for gaps and do not require with-len. */ #include "p9-vec-length-8.h" -/* { dg-final { scan-assembler-times {\mlxvl\M} 30 } } */ -/* { dg-final { scan-assembler-times {\mstxvl\M} 10 } } */ +/* { dg-final { scan-assembler-times {\mlxvl\M} 21 } } */ +/* { dg-final { scan-assembler-times {\mstxvl\M} 7 } } */
[gcc r15-4007] Fix gcc.dg/pr116905.c
https://gcc.gnu.org/g:9175d08f756c1664ecb397fdacca150409dcca49 commit r15-4007-g9175d08f756c1664ecb397fdacca150409dcca49 Author: Richard Biener Date: Wed Oct 2 08:49:06 2024 +0200 Fix gcc.dg/pr116905.c I missed { dg-add-options float16 }. * gcc.dg/pr116905.c: Add float16 options. Diff: --- gcc/testsuite/gcc.dg/pr116905.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/testsuite/gcc.dg/pr116905.c b/gcc/testsuite/gcc.dg/pr116905.c index 0a2b96ac1c16..89de8525b25e 100644 --- a/gcc/testsuite/gcc.dg/pr116905.c +++ b/gcc/testsuite/gcc.dg/pr116905.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-require-effective-target float16 } */ /* { dg-options "-frounding-math" } */ +/* { dg-add-options float16 } */ /* { dg-additional-options "-mavx" { target avx } } */ typedef __attribute__((__vector_size__(16))) _Float16 F;
[gcc r15-4003] RISC-V: Add testcases for form 2 of scalar signed SAT_SUB
https://gcc.gnu.org/g:ed7b3e78183ffed49f197536239812fe77d7d687 commit r15-4003-ged7b3e78183ffed49f197536239812fe77d7d687 Author: Pan Li Date: Thu Sep 26 20:21:10 2024 +0800 RISC-V: Add testcases for form 2 of scalar signed SAT_SUB Form 2: #define DEF_SAT_S_SUB_FMT_2(T, UT, MIN, MAX) \ T __attribute__((noinline)) \ sat_s_sub_##T##_fmt_1 (T x, T y) \ {\ T minus = (UT)x - (UT)y; \ if ((x ^ y) >= 0 || (minus ^ x) >= 0) \ return minus;\ return x < 0 ? MIN : MAX; \ } DEF_SAT_S_SUB_FMT_2(int8_t, uint8_t, INT8_MIN, INT8_MAX) The below test 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/sat_arith.h: Add test helper macros. * gcc.target/riscv/sat_s_sub-2-i16.c: New test. * gcc.target/riscv/sat_s_sub-2-i32.c: New test. * gcc.target/riscv/sat_s_sub-2-i64.c: New test. * gcc.target/riscv/sat_s_sub-2-i8.c: New test. * gcc.target/riscv/sat_s_sub-run-2-i16.c: New test. * gcc.target/riscv/sat_s_sub-run-2-i32.c: New test. * gcc.target/riscv/sat_s_sub-run-2-i64.c: New test. * gcc.target/riscv/sat_s_sub-run-2-i8.c: New test. Signed-off-by: Pan Li Diff: --- gcc/testsuite/gcc.target/riscv/sat_arith.h | 15 +++ gcc/testsuite/gcc.target/riscv/sat_s_sub-2-i16.c | 30 ++ gcc/testsuite/gcc.target/riscv/sat_s_sub-2-i32.c | 28 gcc/testsuite/gcc.target/riscv/sat_s_sub-2-i64.c | 27 +++ gcc/testsuite/gcc.target/riscv/sat_s_sub-2-i8.c| 28 .../gcc.target/riscv/sat_s_sub-run-2-i16.c | 16 .../gcc.target/riscv/sat_s_sub-run-2-i32.c | 16 .../gcc.target/riscv/sat_s_sub-run-2-i64.c | 16 .../gcc.target/riscv/sat_s_sub-run-2-i8.c | 16 9 files changed, 192 insertions(+) diff --git a/gcc/testsuite/gcc.target/riscv/sat_arith.h b/gcc/testsuite/gcc.target/riscv/sat_arith.h index 587f3f8348c2..66d393399a29 100644 --- a/gcc/testsuite/gcc.target/riscv/sat_arith.h +++ b/gcc/testsuite/gcc.target/riscv/sat_arith.h @@ -367,9 +367,24 @@ sat_s_sub_##T##_fmt_1 (T x, T y) \ #define DEF_SAT_S_SUB_FMT_1_WRAP(T, UT, MIN, MAX) \ DEF_SAT_S_SUB_FMT_1(T, UT, MIN, MAX) +#define DEF_SAT_S_SUB_FMT_2(T, UT, MIN, MAX) \ +T __attribute__((noinline)) \ +sat_s_sub_##T##_fmt_2 (T x, T y) \ +{\ + T minus = (UT)x - (UT)y; \ + if ((x ^ y) >= 0 || (minus ^ x) >= 0) \ +return minus;\ + return x < 0 ? MIN : MAX; \ +} +#define DEF_SAT_S_SUB_FMT_2_WRAP(T, UT, MIN, MAX) \ + DEF_SAT_S_SUB_FMT_2(T, UT, MIN, MAX) + #define RUN_SAT_S_SUB_FMT_1(T, x, y) sat_s_sub_##T##_fmt_1(x, y) #define RUN_SAT_S_SUB_FMT_1_WRAP(T, x, y) RUN_SAT_S_SUB_FMT_1(T, x, y) +#define RUN_SAT_S_SUB_FMT_2(T, x, y) sat_s_sub_##T##_fmt_2(x, y) +#define RUN_SAT_S_SUB_FMT_2_WRAP(T, x, y) RUN_SAT_S_SUB_FMT_2(T, x, y) + /**/ /* Saturation Truncate (unsigned and signed) */ /**/ diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_sub-2-i16.c b/gcc/testsuite/gcc.target/riscv/sat_s_sub-2-i16.c new file mode 100644 index ..6aac2c71ba44 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_s_sub-2-i16.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "sat_arith.h" + +/* +** sat_s_sub_int16_t_fmt_2: +** sub\s+[atx][0-9]+,\s*a0,\s*a1 +** xor\s+[atx][0-9]+,\s*a0,\s*a1 +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 +** li\s+[atx][0-9]+,\s*32768 +** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 +** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** neg\s+[atx][0-9]+,\s*[atx][0-9]+ +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ +** slliw\s+a0,\s*a0,\s*16 +** sraiw\s+a0,\s*a0,\s*16 +** ret +*/ +DEF_SAT_S_SUB_FMT_2(int16_t, uint16_t, INT16_MIN, I
[gcc r15-4002] Match: Support form 2 for scalar signed integer SAT_SUB
https://gcc.gnu.org/g:3809b4d6ec385b51af300f570c0ed2895faa2c8e commit r15-4002-g3809b4d6ec385b51af300f570c0ed2895faa2c8e Author: Pan Li Date: Thu Sep 26 20:12:33 2024 +0800 Match: Support form 2 for scalar signed integer SAT_SUB This patch would like to support the form 2 of the scalar signed integer SAT_SUB. Aka below example: Form 2: #define DEF_SAT_S_SUB_FMT_2(T, UT, MIN, MAX) \ T __attribute__((noinline)) \ sat_s_sub_##T##_fmt_1 (T x, T y) \ {\ T minus = (UT)x - (UT)y; \ if ((x ^ y) >= 0 || (minus ^ x) >= 0) \ return minus;\ return x < 0 ? MIN : MAX; \ } DEF_SAT_S_SUB_FMT_2(int8_t, uint8_t, INT8_MIN, INT8_MAX) Before this patch: 4 │ __attribute__((noinline)) 5 │ int8_t sat_s_sub_int8_t_fmt_2 (int8_t x, int8_t y) 6 │ { 7 │ int8_t minus; 8 │ unsigned char x.0_1; 9 │ unsigned char y.1_2; 10 │ unsigned char _3; 11 │ signed char _4; 12 │ signed char _5; 13 │ int8_t _6; 14 │ _Bool _11; 15 │ signed char _12; 16 │ signed char _13; 17 │ signed char _14; 18 │ signed char _15; 19 │ 20 │ ;; basic block 2, loop depth 0 21 │ ;;pred: ENTRY 22 │ x.0_1 = (unsigned char) x_7(D); 23 │ y.1_2 = (unsigned char) y_8(D); 24 │ _3 = x.0_1 - y.1_2; 25 │ minus_9 = (int8_t) _3; 26 │ _4 = x_7(D) ^ y_8(D); 27 │ _5 = x_7(D) ^ minus_9; 28 │ _15 = _4 & _5; 29 │ if (_15 >= 0) 30 │ goto ; [42.57%] 31 │ else 32 │ goto ; [57.43%] 33 │ ;;succ: 4 34 │ ;;3 35 │ 36 │ ;; basic block 3, loop depth 0 37 │ ;;pred: 2 38 │ _11 = x_7(D) < 0; 39 │ _12 = (signed char) _11; 40 │ _13 = -_12; 41 │ _14 = _13 ^ 127; 42 │ ;;succ: 4 43 │ 44 │ ;; basic block 4, loop depth 0 45 │ ;;pred: 2 46 │ ;;3 47 │ # _6 = PHI 48 │ return _6; 49 │ ;;succ: EXIT 50 │ 51 │ } After this patch: 4 │ __attribute__((noinline)) 5 │ int8_t sat_s_sub_int8_t_fmt_2 (int8_t x, int8_t y) 6 │ { 7 │ int8_t _6; 8 │ 9 │ ;; basic block 2, loop depth 0 10 │ ;;pred: ENTRY 11 │ _6 = .SAT_SUB (x_7(D), y_8(D)); [tail call] 12 │ return _6; 13 │ ;;succ: EXIT 14 │ 15 │ } 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: Add case 2 matching pattern for signed SAT_SUB. Signed-off-by: Pan Li Diff: --- gcc/match.pd | 14 ++ 1 file changed, 14 insertions(+) diff --git a/gcc/match.pd b/gcc/match.pd index 5ec31ef6269a..ba83f0f29e61 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3374,6 +3374,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) @2) (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type +/* Signed saturation sub, case 2: + T minus = (T)((UT)X - (UT)Y); + SAT_S_SUB = (X ^ Y) & (X ^ minus) < 0 ? (-(T)(X < 0) ^ MAX) : minus; + + The T and UT are type pair like T=int8_t, UT=uint8_t. */ +(match (signed_integer_sat_sub @0 @1) + (cond^ (ge (bit_and:c (bit_xor:c @0 @1) + (bit_xor @0 (nop_convert@2 (minus (nop_convert @0) +(nop_convert @1) + integer_zerop) + @2 + (bit_xor:c (negate (convert (lt @0 integer_zerop))) max_value)) + (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type + /* Unsigned saturation truncate, case 1, sizeof (WT) > sizeof (NT). SAT_U_TRUNC = (NT)x | (NT)(-(X > (WT)(NT)(-1))). */ (match (unsigned_integer_sat_trunc @0)
[gcc r15-4004] tree-optimization/116654 - missed dr_explicit_realign[_optimized] with SLP
https://gcc.gnu.org/g:e592ea8ddffb44bab52d36d9862bb39ffae4d144 commit r15-4004-ge592ea8ddffb44bab52d36d9862bb39ffae4d144 Author: Richard Biener Date: Tue Oct 1 15:17:18 2024 +0200 tree-optimization/116654 - missed dr_explicit_realign[_optimized] with SLP With single-lane SLP we miss to use the power realing loads causing some testsuite FAILs. r14-2430-g4736ddd11874fe exempted SLP of non-grouped accesses because that could have been only splats where the scheme isn't used anyway, but now with single-lane SLP it can be contiguous accesses. PR tree-optimization/116654 * tree-vect-data-refs.cc (vect_supportable_dr_alignment): Treat non-grouped accesses like non-SLP. Diff: --- gcc/tree-vect-data-refs.cc | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc index fe7fdec4ba0d..920e3c120a66 100644 --- a/gcc/tree-vect-data-refs.cc +++ b/gcc/tree-vect-data-refs.cc @@ -7170,11 +7170,11 @@ vect_supportable_dr_alignment (vec_info *vinfo, dr_vec_info *dr_info, same alignment, instead it depends on the SLP group size. */ if (loop_vinfo && STMT_SLP_TYPE (stmt_info) - && (!STMT_VINFO_GROUPED_ACCESS (stmt_info) - || !multiple_p (LOOP_VINFO_VECT_FACTOR (loop_vinfo) - * (DR_GROUP_SIZE - (DR_GROUP_FIRST_ELEMENT (stmt_info))), - TYPE_VECTOR_SUBPARTS (vectype + && STMT_VINFO_GROUPED_ACCESS (stmt_info) + && !multiple_p (LOOP_VINFO_VECT_FACTOR (loop_vinfo) + * (DR_GROUP_SIZE + (DR_GROUP_FIRST_ELEMENT (stmt_info))), + TYPE_VECTOR_SUBPARTS (vectype))) ; else if (!loop_vinfo || (nested_in_vect_loop