[gcc r15-6292] Fortran: Fix associate with derived type array construtor [PR117347]
https://gcc.gnu.org/g:9684e70952ac159ce0b838533ce4e9c98474e1a8 commit r15-6292-g9684e70952ac159ce0b838533ce4e9c98474e1a8 Author: Andre Vehreschild Date: Fri Dec 13 09:06:11 2024 +0100 Fortran: Fix associate with derived type array construtor [PR117347] gcc/fortran/ChangeLog: PR fortran/117347 * primary.cc (gfc_match_varspec): Add array constructors for guessing their type like with unresolved function calls. gcc/testsuite/ChangeLog: * gfortran.dg/associate_71.f90: New test. Diff: --- gcc/fortran/primary.cc | 1 + gcc/testsuite/gfortran.dg/associate_71.f90 | 39 ++ 2 files changed, 40 insertions(+) diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc index 1db27929eebd..ab49eac450f6 100644 --- a/gcc/fortran/primary.cc +++ b/gcc/fortran/primary.cc @@ -2423,6 +2423,7 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag, component name 're' or 'im' could be found. */ if (tgt_expr && (tgt_expr->expr_type == EXPR_FUNCTION + || tgt_expr->expr_type == EXPR_ARRAY || (!resolved && tgt_expr->expr_type == EXPR_OP)) && (sym->ts.type == BT_UNKNOWN || (inferred_type && sym->ts.type != BT_COMPLEX)) diff --git a/gcc/testsuite/gfortran.dg/associate_71.f90 b/gcc/testsuite/gfortran.dg/associate_71.f90 new file mode 100644 index ..8f67b53180e5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/associate_71.f90 @@ -0,0 +1,39 @@ +! { dg-do run } +! +! Check that pr117347 is fixed. +! Contributed by Ivan Pribec + +program pr117347 + implicit none + + type :: point + real :: x = 42. + end type point + + type(point) :: mypoint + real:: pi(1) + associate (points => mypoint ) +pi(:) = points% x + end associate + if (any(pi /= 42)) stop 1 + associate (points => (mypoint)) +pi(:) = points% x + end associate + if (any(pi /= 42)) stop 2 + associate (points => [mypoint]) +pi(:) = points% x + end associate + if (any(pi /= 42)) stop 3 + associate (points => [rpoint()]) +pi(:) = points% x + end associate + if (any(pi /= 35)) stop 4 + +contains + + function rpoint() result(r) +type(point) :: r +r%x = 35 + end function +end program +
[gcc r15-6295] ipa: Better value ranges for pointer integer constants
https://gcc.gnu.org/g:1eb41aeb49a491f5b18d160074e651a76afc655a commit r15-6295-g1eb41aeb49a491f5b18d160074e651a76afc655a Author: Martin Jambor Date: Tue Dec 17 11:17:14 2024 +0100 ipa: Better value ranges for pointer integer constants When looking into cases where we know an actual argument of a call is a constant but we don't generate a singleton value-range for the jump function, I found out that the special handling of pointer constants does not work well for constant zero pointer values. In fact the code only attempts to see if it can figure out that an argument is not zero and if it can figure out any alignment information. With this patch, we try to use the value_range that ranger can give us in the jump function if we can and we query ranger for all kinds of arguments, not just SSA_NAMES (and so also pointer integer constants). If we cannot figure out a useful range we fall back again on figuring out non-NULLness with tree_single_nonzero_warnv_p. With this patch, we generate [prange] struct S * [0, 0] MASK 0x0 VALUE 0x0 instead of for example: [prange] struct S * [0, +INF] MASK 0xfff0 VALUE 0x0 for a zero constant passed in a call. If you are wondering why we check whether the value range obtained from range_of_expr can be undefined, even when the function returns true, that is because that can apparently happen fro default-definition SSA_NAMEs. gcc/ChangeLog: 2024-11-15 Martin Jambor * ipa-prop.cc (ipa_compute_jump_functions_for_edge): Try harder to use the value range obtained from ranger for pointer values. Diff: --- gcc/ipa-prop.cc | 35 --- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index ae309ec78a2d..f0b915ba2be1 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -2396,28 +2396,27 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, value_range vr (TREE_TYPE (arg)); if (POINTER_TYPE_P (TREE_TYPE (arg))) { - bool addr_nonzero = false; - bool strict_overflow = false; - - if (TREE_CODE (arg) == SSA_NAME - && param_type - && get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt) - && vr.nonzero_p ()) - addr_nonzero = true; - else if (tree_single_nonzero_warnv_p (arg, &strict_overflow)) - addr_nonzero = true; - - if (addr_nonzero) - vr.set_nonzero (TREE_TYPE (arg)); - + if (!get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt) + || vr.varying_p () + || vr.undefined_p ()) + { + bool strict_overflow = false; + if (tree_single_nonzero_warnv_p (arg, &strict_overflow)) + vr.set_nonzero (TREE_TYPE (arg)); + else + vr.set_varying (TREE_TYPE (arg)); + } + gcc_assert (!vr.undefined_p ()); unsigned HOST_WIDE_INT bitpos; - unsigned align, prec = TYPE_PRECISION (TREE_TYPE (arg)); + unsigned align = BITS_PER_UNIT; - get_pointer_alignment_1 (arg, &align, &bitpos); + if (!vr.singleton_p ()) + get_pointer_alignment_1 (arg, &align, &bitpos); if (align > BITS_PER_UNIT && opt_for_fn (cs->caller->decl, flag_ipa_bit_cp)) { + unsigned prec = TYPE_PRECISION (TREE_TYPE (arg)); wide_int mask = wi::bit_and_not (wi::mask (prec, false, prec), wide_int::from (align / BITS_PER_UNIT - 1, @@ -2425,12 +2424,10 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, wide_int value = wide_int::from (bitpos / BITS_PER_UNIT, prec, UNSIGNED); irange_bitmask bm (value, mask); - if (!addr_nonzero) - vr.set_varying (TREE_TYPE (arg)); vr.update_bitmask (bm); ipa_set_jfunc_vr (jfunc, vr); } - else if (addr_nonzero) + else if (!vr.varying_p ()) ipa_set_jfunc_vr (jfunc, vr); else gcc_assert (!jfunc->m_vr);
[gcc r15-6296] ipa: Improve how we derive value ranges from IPA invariants
https://gcc.gnu.org/g:5d740f56a162702a33379789a4d6134d9733aa71 commit r15-6296-g5d740f56a162702a33379789a4d6134d9733aa71 Author: Martin Jambor Date: Tue Dec 17 11:17:14 2024 +0100 ipa: Improve how we derive value ranges from IPA invariants I believe that the current function ipa_range_set_and_normalize lacks a check that a base of an ADDR_EXPR lacks a test whether the base really cannot be NULL, so this patch adds it. Moreover, I never liked the name as I do not think it makes the value of ranges any more normal but rather just special-cases non-zero ip_invariant pointers. Therefore, I have given it a different name and moved it to a .cc file, our LTO bootstrap should inline (and/or split) it if necessary anyway. Because, as Honza correctly pointed out, deriving non-NULLness from a pointer depends on flag_delete_null_pointer_checks which is an optimization flag and thus depends on a given function, in this version of the patch ipa_get_range_from_ip_invariant gets a context_node parameter for that purpose. This then needs to be used within symtab_node::nonzero_address which gets a special overload in which the value of the flag can be provided as a parameter. gcc/ChangeLog: 2024-12-11 Martin Jambor * cgraph.h (symtab_node): Add a new overload of nonzero_address. * symtab.cc (symtab_node::nonzero_address): Add a new overload whith a parameter for delete_null_pointer_checks. Make the original overload call the new one which has retains the actual implementation. * ipa-prop.h (ipa_get_range_from_ip_invariant): Declare. (ipa_range_set_and_normalize): Remove. * ipa-prop.cc (ipa_get_range_from_ip_invariant): New function. (ipa_range_set_and_normalize): Remove. * ipa-cp.cc (ipa_vr_intersect_with_arith_jfunc): Add a new parameter context_node. Use ipa_get_range_from_ip_invariant instead of ipa_range_set_and_normalize and pass to it the new parameter. (ipa_value_range_from_jfunc): Pass cs->caller as the context_node to ipa_vr_intersect_with_arith_jfunc. (propagate_vr_across_jump_function): Likewise. (ipa_get_range_from_ip_invariant): New function. * ipa-fnsummary.cc (evaluate_conditions_for_known_args): Use ipa_get_range_from_ip_invariant instead of ipa_range_set_and_normalize Diff: --- gcc/cgraph.h | 4 gcc/ipa-cp.cc| 12 gcc/ipa-fnsummary.cc | 4 ++-- gcc/ipa-prop.cc | 37 + gcc/ipa-prop.h | 15 +-- gcc/symtab.cc| 21 +++-- 6 files changed, 67 insertions(+), 26 deletions(-) diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 50bae96de4cf..9b4cb6383afc 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -431,6 +431,10 @@ public: /* Return true if ONE and TWO are part of the same COMDAT group. */ inline bool in_same_comdat_group_p (symtab_node *target); + /* Return true if symbol is known to be nonzero, assume that + flag_delete_null_pointer_checks is equal to delete_null_pointer_checks. */ + bool nonzero_address (bool delete_null_pointer_checks); + /* Return true if symbol is known to be nonzero. */ bool nonzero_address (); diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc index a664bc03f62a..5d7b3d25df5d 100644 --- a/gcc/ipa-cp.cc +++ b/gcc/ipa-cp.cc @@ -1693,11 +1693,14 @@ ipa_vr_operation_and_type_effects (vrange &dst_vr, /* Given a PASS_THROUGH jump function JFUNC that takes as its source SRC_VR of SRC_TYPE and the result needs to be DST_TYPE, if any value range information - can be deduced at all, intersect VR with it. */ + can be deduced at all, intersect VR with it. CONTEXT_NODE is the call graph + node representing the function for which optimization flags should be + evaluated. */ static void ipa_vr_intersect_with_arith_jfunc (vrange &vr, ipa_jump_func *jfunc, + cgraph_node *context_node, const value_range &src_vr, tree src_type, tree dst_type) @@ -1720,7 +1723,7 @@ ipa_vr_intersect_with_arith_jfunc (vrange &vr, if (!handler) return; value_range op_vr (TREE_TYPE (operand)); - ipa_range_set_and_normalize (op_vr, operand); + ipa_get_range_from_ip_invariant (op_vr, operand, context_node); tree operation_type; if (TREE_CODE_CLASS (operation) == tcc_comparison) @@ -1776,7 +1779,8 @@ ipa_value_range_from_jfunc (vrange &vr, value_range srcvr; (*sum->m_vr)[idx].get_vrange (srcvr); - ipa_vr_intersect_with_arith_jfunc (vr, jfunc, srcvr, src_type, parm_type); + ipa_vr_intersect_with_arith_jfunc (vr, jfunc, cs->caller, srcvr, src_type, +
[gcc r15-6294] ipa: Skip widening type conversions in jump function constructions
https://gcc.gnu.org/g:96fb71883d438bdb241fdf9c7d12f945c5ba0c7f commit r15-6294-g96fb71883d438bdb241fdf9c7d12f945c5ba0c7f Author: Martin Jambor Date: Tue Dec 17 11:17:14 2024 +0100 ipa: Skip widening type conversions in jump function constructions Originally, we did not stream any formal parameter types into WPA and were generally very conservative when it came to type mismatches in IPA-CP. Over the time, mismatches that happen in code and blew up in WPA made us to be much more resilient and also to stream the types of the parameters which we now use commonly. With that information, we can safely skip conversions when looking at the IL from which we build jump functions and then simply fold convert the constants and ranges to the resulting type, as long as we are careful that performing the corresponding folding of constants gives the corresponding results. In order to do that, we must ensure that the old value can be represented in the new one without any loss. With this change, we can nicely propagate non-NULLness in IPA-VR as demonstrated with the new test case. I have gone through all other uses of (all components of) jump functions which could be affected by this and verified they do indeed check types and can handle mismatches. gcc/ChangeLog: 2024-12-11 Martin Jambor * ipa-prop.cc: Include vr-values.h. (skip_a_safe_conversion_op): New function. (ipa_compute_jump_functions_for_edge): Use it. gcc/testsuite/ChangeLog: 2024-11-01 Martin Jambor * gcc.dg/ipa/vrp9.c: New test. Diff: --- gcc/ipa-prop.cc | 40 ++ gcc/testsuite/gcc.dg/ipa/vrp9.c | 48 + 2 files changed, 88 insertions(+) diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index 3d72794e37c4..ae309ec78a2d 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see #include "attr-fnspec.h" #include "gimple-range.h" #include "value-range-storage.h" +#include "vr-values.h" /* Function summary where the parameter infos are actually stored. */ ipa_node_params_t *ipa_node_params_sum = NULL; @@ -2311,6 +2312,44 @@ ipa_set_jfunc_vr (ipa_jump_func *jf, const ipa_vr &vr) ipa_set_jfunc_vr (jf, tmp); } + +/* If T is an SSA_NAME that is the result of a simple type conversion statement + from an integer type to another integer type which is known to be able to + represent the values the operand of the conversion can hold, return the + operand of that conversion, otherwise return T. */ + +static tree +skip_a_safe_conversion_op (tree t) +{ + if (TREE_CODE (t) != SSA_NAME + || SSA_NAME_IS_DEFAULT_DEF (t)) +return t; + + gimple *def = SSA_NAME_DEF_STMT (t); + if (!is_gimple_assign (def) + || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)) + || !INTEGRAL_TYPE_P (TREE_TYPE (t)) + || !INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def +return t; + + tree rhs1 = gimple_assign_rhs1 (def); + if (TYPE_PRECISION (TREE_TYPE (t)) + >= TYPE_PRECISION (TREE_TYPE (rhs1))) +return gimple_assign_rhs1 (def); + + value_range vr (TREE_TYPE (rhs1)); + if (!get_range_query (cfun)->range_of_expr (vr, rhs1, def) + || vr.undefined_p ()) +return t; + + irange &ir = as_a (vr); + if (range_fits_type_p (&ir, TYPE_PRECISION (TREE_TYPE (t)), +TYPE_SIGN (TREE_TYPE (t + return gimple_assign_rhs1 (def); + + return t; +} + /* Compute jump function for all arguments of callsite CS and insert the information in the jump_functions array in the ipa_edge_args corresponding to this callsite. */ @@ -2415,6 +2454,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, gcc_assert (!jfunc->m_vr); } + arg = skip_a_safe_conversion_op (arg); if (is_gimple_ip_invariant (arg) || (VAR_P (arg) && is_global_var (arg) diff --git a/gcc/testsuite/gcc.dg/ipa/vrp9.c b/gcc/testsuite/gcc.dg/ipa/vrp9.c new file mode 100644 index ..461a2e757d2c --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/vrp9.c @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int some_f1 (int); +int some_f2 (int); +int some_f3 (int); + +void remove_this_call (); + +int g; + +static int __attribute__((noinline)) +bar (int p) +{ + if (p) +remove_this_call (); + return g++; +} + +static int __attribute__((noinline)) +foo (int (*f)(int)) +{ + return bar (f == (void *)0); +} + +int +baz1 (void) +{ + int (*f)(int); + if (g) +f = some_f1; + else +f = some_f2; + return foo (f); +} + +int +baz2 (void) +{ + int (*f)(int); + if (g) +f = some_f2; + else +f = some_f3; + return foo (f); +} + +/* { dg-final { scan-tree-dump-not "remove_this_call" "
[gcc r14-11098] Fortran: Pointer fcn results must not be finalized [PR117897]
https://gcc.gnu.org/g:3b6ed0c74139faed62b7d60804521aed67e40b2b commit r14-11098-g3b6ed0c74139faed62b7d60804521aed67e40b2b Author: Paul Thomas Date: Sun Dec 15 10:42:34 2024 + Fortran: Pointer fcn results must not be finalized [PR117897] 2024-12-15 Paul Thomas gcc/fortran PR fortran/117897 * trans-expr.cc (gfc_trans_assignment_1): RHS pointer function results must not be finalized. gcc/testsuite/ PR fortran/117897 * gfortran.dg/finalize_59.f90: New test. (cherry picked from commit a87bf1d20a37bb69c9fa6d2211ffd963aa69240d) Diff: --- gcc/fortran/trans-expr.cc | 9 +- gcc/testsuite/gfortran.dg/finalize_59.f90 | 245 ++ 2 files changed, 253 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 9d04b99af6e7..10eade22f2a2 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -12289,13 +12289,20 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag, && (expr2->ts.type == BT_CLASS || gfc_may_be_finalized (expr2->ts))) { expr2->must_finalize = 1; + /* F2023 7.5.6.3: If an executable construct references a nonpointer +function, the result is finalized after execution of the innermost +executable construct containing the reference. */ + if (expr2->expr_type == EXPR_FUNCTION + && (gfc_expr_attr (expr2).pointer + || (expr2->ts.type == BT_CLASS && CLASS_DATA (expr2)->attr.class_pointer))) + expr2->must_finalize = 0; /* F2008 4.5.6.3 para 5: If an executable construct references a structure constructor or array constructor, the entity created by the constructor is finalized after execution of the innermost executable construct containing the reference. These finalizations were later deleted by the Combined Techical Corrigenda 1 TO 4 for fortran 2008 (f08/0011). */ - if (gfc_notification_std (GFC_STD_F2018_DEL) + else if (gfc_notification_std (GFC_STD_F2018_DEL) && (expr2->expr_type == EXPR_STRUCTURE || expr2->expr_type == EXPR_ARRAY)) expr2->must_finalize = 0; diff --git a/gcc/testsuite/gfortran.dg/finalize_59.f90 b/gcc/testsuite/gfortran.dg/finalize_59.f90 new file mode 100644 index ..8be5f7123a1a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/finalize_59.f90 @@ -0,0 +1,245 @@ +! { dg-do run } +! +! Test the fix for PR117897 in which the rhs of the pointer assignment at line +! 216 below was marked as being finalizable, contrary to F2023 7.5.6.3 for +! ordinary assignment and certainly wrong in this context. +! +! Contributed by Jean Gual +! +Module Uef_Classe_Vector +! Ce module implemente le vector de la STL du C++ +Private +CHARACTER (len=3), Parameter :: UEF_PAR_CHAINE_NON_RENSEIGNEE = "N_R" +real, parameter :: UEF_par_vector_progression_ratio = 2 +Integer, parameter :: UEF_par_vector_initial_lenght = 10 + +Type, abstract, public :: Uef_Vector_element +Logical, public :: m_Element_pointe = .false. +End type Uef_Vector_element + +Type, private :: Uef_Pointeur_element ! Classe pointeur +Class (Uef_Vector_element), public, pointer :: m_ptr_element => null() +End type Uef_Pointeur_element + +Type, public :: Uef_Vector ! Vecteur des classes pointeur +integer , private :: m_position_fin = 0 +type(Uef_Pointeur_element), private, allocatable, dimension(:) :: m_les_pointeur_element +Character (:), private, allocatable :: m_label +Class (Uef_Vector_element), allocatable, private:: m_type_element +logical,private :: m_polymorphe = .false. + Contains +PROCEDURE :: create => Vector_create +PROCEDURE :: add => Vector_add +PROCEDURE :: Pointer => Vector_pointer +PROCEDURE :: size=> vector_size +End Type Uef_Vector + +Contains +! +! Vector_create : Cree un vector non deja alloue avec une taille initiale eventuelle +! +Subroutine Vector_create(le_vector, label, type_element, opt_taille, opt_polymorphe) +! parametres en entree/sortie +Class(Uef_Vector),intent (inout):: le_vector +Character (len=*),intent(in):: label +Class (Uef_Vector_element),intent(in) :: type_element +Integer, intent(in), optional :: opt_taille +Logical, intent(in), optional :: opt_polymorphe + +! parametres locaux +integer :: taille_initiale +! +!-DEBUT-
[gcc r13-9258] Fortran: Pointer fcn results must not be finalized [PR117897]
https://gcc.gnu.org/g:9b720ef00339d44050ebdaa9ac69b0c49588c501 commit r13-9258-g9b720ef00339d44050ebdaa9ac69b0c49588c501 Author: Paul Thomas Date: Sun Dec 15 10:42:34 2024 + Fortran: Pointer fcn results must not be finalized [PR117897] 2024-12-15 Paul Thomas gcc/fortran PR fortran/117897 * trans-expr.cc (gfc_trans_assignment_1): RHS pointer function results must not be finalized. gcc/testsuite/ PR fortran/117897 * gfortran.dg/finalize_59.f90: New test. (cherry picked from commit a87bf1d20a37bb69c9fa6d2211ffd963aa69240d) Diff: --- gcc/fortran/trans-expr.cc | 9 +- gcc/testsuite/gfortran.dg/finalize_59.f90 | 245 ++ 2 files changed, 253 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index df109bd40547..571916654129 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -11881,13 +11881,20 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag, && (expr2->ts.type == BT_CLASS || gfc_may_be_finalized (expr2->ts))) { expr2->must_finalize = 1; + /* F2023 7.5.6.3: If an executable construct references a nonpointer +function, the result is finalized after execution of the innermost +executable construct containing the reference. */ + if (expr2->expr_type == EXPR_FUNCTION + && (gfc_expr_attr (expr2).pointer + || (expr2->ts.type == BT_CLASS && CLASS_DATA (expr2)->attr.class_pointer))) + expr2->must_finalize = 0; /* F2008 4.5.6.3 para 5: If an executable construct references a structure constructor or array constructor, the entity created by the constructor is finalized after execution of the innermost executable construct containing the reference. These finalizations were later deleted by the Combined Techical Corrigenda 1 TO 4 for fortran 2008 (f08/0011). */ - if (gfc_notification_std (GFC_STD_F2018_DEL) + else if (gfc_notification_std (GFC_STD_F2018_DEL) && (expr2->expr_type == EXPR_STRUCTURE || expr2->expr_type == EXPR_ARRAY)) expr2->must_finalize = 0; diff --git a/gcc/testsuite/gfortran.dg/finalize_59.f90 b/gcc/testsuite/gfortran.dg/finalize_59.f90 new file mode 100644 index ..8be5f7123a1a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/finalize_59.f90 @@ -0,0 +1,245 @@ +! { dg-do run } +! +! Test the fix for PR117897 in which the rhs of the pointer assignment at line +! 216 below was marked as being finalizable, contrary to F2023 7.5.6.3 for +! ordinary assignment and certainly wrong in this context. +! +! Contributed by Jean Gual +! +Module Uef_Classe_Vector +! Ce module implemente le vector de la STL du C++ +Private +CHARACTER (len=3), Parameter :: UEF_PAR_CHAINE_NON_RENSEIGNEE = "N_R" +real, parameter :: UEF_par_vector_progression_ratio = 2 +Integer, parameter :: UEF_par_vector_initial_lenght = 10 + +Type, abstract, public :: Uef_Vector_element +Logical, public :: m_Element_pointe = .false. +End type Uef_Vector_element + +Type, private :: Uef_Pointeur_element ! Classe pointeur +Class (Uef_Vector_element), public, pointer :: m_ptr_element => null() +End type Uef_Pointeur_element + +Type, public :: Uef_Vector ! Vecteur des classes pointeur +integer , private :: m_position_fin = 0 +type(Uef_Pointeur_element), private, allocatable, dimension(:) :: m_les_pointeur_element +Character (:), private, allocatable :: m_label +Class (Uef_Vector_element), allocatable, private:: m_type_element +logical,private :: m_polymorphe = .false. + Contains +PROCEDURE :: create => Vector_create +PROCEDURE :: add => Vector_add +PROCEDURE :: Pointer => Vector_pointer +PROCEDURE :: size=> vector_size +End Type Uef_Vector + +Contains +! +! Vector_create : Cree un vector non deja alloue avec une taille initiale eventuelle +! +Subroutine Vector_create(le_vector, label, type_element, opt_taille, opt_polymorphe) +! parametres en entree/sortie +Class(Uef_Vector),intent (inout):: le_vector +Character (len=*),intent(in):: label +Class (Uef_Vector_element),intent(in) :: type_element +Integer, intent(in), optional :: opt_taille +Logical, intent(in), optional :: opt_polymorphe + +! parametres locaux +integer :: taille_initiale +! +!-DEBUT--
[gcc r15-6305] testsuite: arm: Mark pr81812.C as xfail for thumb1
https://gcc.gnu.org/g:f111d8e20b671ee97d4ed835102839e44a2a2edc commit r15-6305-gf111d8e20b671ee97d4ed835102839e44a2a2edc Author: Torbjörn SVENSSON Date: Sun Nov 10 20:15:13 2024 +0100 testsuite: arm: Mark pr81812.C as xfail for thumb1 Test fails for Cortex-M0 with: .../pr81812.C:6:8: error: generic thunk code fails for method 'virtual void ChildNode::_ZTv0_n12_NK9ChildNode5errorEz(...) const' which uses '...' According to PR108277, it's expected that thumb1 targets does not support empty virtual functions with ellipsis. gcc/testsuite/ChangeLog: * g++.dg/torture/pr81812.C: Add xfail for thumb1. Signed-off-by: Torbjörn SVENSSON Diff: --- gcc/testsuite/g++.dg/torture/pr81812.C | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcc/testsuite/g++.dg/torture/pr81812.C b/gcc/testsuite/g++.dg/torture/pr81812.C index d235e2375888..b5c621d2beb2 100644 --- a/gcc/testsuite/g++.dg/torture/pr81812.C +++ b/gcc/testsuite/g++.dg/torture/pr81812.C @@ -1,3 +1,5 @@ +// { dg-xfail-if "PR108277" { arm_thumb1 } } + struct Error { virtual void error(... ) const; };
[gcc r15-6307] [PATCH] RISC-V: optimization on checking certain bits set ((x & mask) == val)
https://gcc.gnu.org/g:d17b09c07a1da0e3950718aabc2cbdb90cae402b commit r15-6307-gd17b09c07a1da0e3950718aabc2cbdb90cae402b Author: Oliver Kozul Date: Tue Dec 17 07:44:33 2024 -0700 [PATCH] RISC-V: optimization on checking certain bits set ((x & mask) == val) The patch optimizes code generation for comparisons of the form X & C1 == C2 by converting them to (X | ~C1) == (C2 | ~C1). C1 is a constant that requires li and addi to be loaded, while ~C1 requires a single lui instruction. As the values of C1 and C2 are not visible within the equality expression, a plus pattern is matched instead. PR target/114087 gcc/ChangeLog: * config/riscv/riscv.md (*lui_constraint_and_to_or): New pattern gcc/testsuite/ChangeLog: * gcc.target/riscv/pr114087-1.c: New test. Diff: --- gcc/config/riscv/riscv.md | 28 gcc/testsuite/gcc.target/riscv/pr114087-1.c | 16 2 files changed, 44 insertions(+) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 1eec51c117a7..6c6155ceeb83 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -858,6 +858,34 @@ [(set_attr "type" "arith") (set_attr "mode" "SI")]) +;; Transform (X & C1) + C2 into (X | ~C1) - (-C2 | ~C1) +;; Where C1 is not a LUI operand, but ~C1 is a LUI operand + +(define_insn_and_split "*lui_constraint_and_to_or" + [(set (match_operand:ANYI 0 "register_operand" "=r") + (plus:ANYI (and:ANYI (match_operand:ANYI 1 "register_operand" "r") +(match_operand 2 "const_int_operand")) +(match_operand 3 "const_int_operand"))) + (clobber (match_scratch:X 4 "=&r"))] + "LUI_OPERAND (~INTVAL (operands[2])) + && ((INTVAL (operands[2]) & (-INTVAL (operands[3]))) + == (-INTVAL (operands[3]))) + && riscv_const_insns (operands[3], false) + && (riscv_const_insns + (GEN_INT (~INTVAL (operands[2]) | -INTVAL (operands[3])), false) + <= riscv_const_insns (operands[3], false))" + "#" + "&& reload_completed" + [(set (match_dup 4) (match_dup 5)) + (set (match_dup 0) (ior:X (match_dup 1) (match_dup 4))) + (set (match_dup 4) (match_dup 6)) + (set (match_dup 0) (minus:X (match_dup 0) (match_dup 4)))] + { +operands[5] = GEN_INT (~INTVAL (operands[2])); +operands[6] = GEN_INT ((~INTVAL (operands[2])) | (-INTVAL (operands[3]))); + } + [(set_attr "type" "arith")]) + ;; ;; ;; diff --git a/gcc/testsuite/gcc.target/riscv/pr114087-1.c b/gcc/testsuite/gcc.target/riscv/pr114087-1.c new file mode 100644 index ..9df02db6d5df --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr114087-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d" } */ + +#include +#include + +static uint32_t mask1 = 0x5FFF; +static uint32_t val1 = 0x14501DEF; + +bool pred1a(uint32_t x) { + return ((x & mask1) == val1); +} + +/* { dg-final { scan-assembler {or\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+} } } */
[gcc r15-6306] RISC-V: Remove svvptc from riscv-ext-bitmask.def
https://gcc.gnu.org/g:d24a5e2d381b290d4def659ed83e969b65d07f02 commit r15-6306-gd24a5e2d381b290d4def659ed83e969b65d07f02 Author: Yangyu Chen Date: Tue Dec 17 07:41:05 2024 -0700 RISC-V: Remove svvptc from riscv-ext-bitmask.def There should be no svvptc in the riscv-ext-bitmask.def file since it has not yet been added to the RISC-V C API Specification or the Linux hwprobe. And there is no need for userspace software to know that this extension exists. So remove it from the riscv-ext-bitmask.def file. Fixes: e4f4b2dc08 ("RISC-V: Minimal support for svvptc extension.") Signed-off-by: Yangyu Chen gcc/ChangeLog: * common/config/riscv/riscv-ext-bitmask.def (RISCV_EXT_BITMASK): Remove svvptc. Diff: --- gcc/common/config/riscv/riscv-ext-bitmask.def | 1 - 1 file changed, 1 deletion(-) diff --git a/gcc/common/config/riscv/riscv-ext-bitmask.def b/gcc/common/config/riscv/riscv-ext-bitmask.def index a733533df98e..ca5df1740f3f 100644 --- a/gcc/common/config/riscv/riscv-ext-bitmask.def +++ b/gcc/common/config/riscv/riscv-ext-bitmask.def @@ -79,6 +79,5 @@ RISCV_EXT_BITMASK ("zcd", 1, 4) RISCV_EXT_BITMASK ("zcf", 1, 5) RISCV_EXT_BITMASK ("zcmop",1, 6) RISCV_EXT_BITMASK ("zawrs",1, 7) -RISCV_EXT_BITMASK ("svvptc", 1, 8) #undef RISCV_EXT_BITMASK
[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Correction bornes descripteur null
https://gcc.gnu.org/g:da5ac05fe24322022f5c004b266c864f7b58b69e commit da5ac05fe24322022f5c004b266c864f7b58b69e Author: Mikael Morin Date: Tue Dec 17 15:48:04 2024 +0100 Correction bornes descripteur null Diff: --- gcc/fortran/trans-expr.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 758c45b7d347..a6480077a3bc 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -146,8 +146,8 @@ gfc_conv_null_array_descriptor (gfc_se *se, gfc_symbol *sym, gfc_expr *expr) for (int i = 0; i < expr->rank; i++) { - lower[i] = gfc_index_zero_node; - upper[i] = gfc_index_one_node; + lower[i] = NULL_TREE; + upper[i] = NULL_TREE; } tree elt_type = gfc_typenode_for_spec (&sym->ts);
[gcc(refs/users/aoliva/heads/testme)] ifcombine field merge: handle bitfield zero tests in range tests
https://gcc.gnu.org/g:30cf6dfbb6e10943a11785e0c056d5df0a9c583a commit 30cf6dfbb6e10943a11785e0c056d5df0a9c583a Author: Alexandre Oliva Date: Tue Dec 17 11:22:23 2024 -0300 ifcombine field merge: handle bitfield zero tests in range tests Diff: --- gcc/gimple-fold.cc| 46 --- gcc/testsuite/gcc.dg/field-merge-15.c | 36 +++ 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 06913d57f8ae..514d19ef37cb 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7509,8 +7509,10 @@ gimple_binop_def_p (enum tree_code code, tree t, tree op[2]) *PREVERSEP is set to the storage order of the field. - *PAND_MASK is set to the mask found in a BIT_AND_EXPR, if any. - If PAND_MASK *is NULL, BIT_AND_EXPR is not recognized. + *PAND_MASK is set to the mask found in a BIT_AND_EXPR, if any. If + PAND_MASK *is NULL, BIT_AND_EXPR is not recognized. If *PAND_MASK + is initially set to a mask with nonzero precision, that mask is + combined with the found mask, or adjusted in precision to match. *XOR_P is to be FALSE if EXP might be a XOR used in a compare, in which case, if XOR_CMP_OP is a zero constant, it will be overridden with *PEXP, @@ -7561,14 +7563,30 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, exp = res_ops[0]; } - /* Recognize and save a masking operation. */ + /* Recognize and save a masking operation. Combine it with an + incoming mask. */ if (pand_mask && gimple_binop_def_p (BIT_AND_EXPR, exp, res_ops) && uniform_integer_cst_p (res_ops[1])) { loc[1] = gimple_location (SSA_NAME_DEF_STMT (exp)); exp = res_ops[0]; and_mask = wi::to_wide (res_ops[1]); + unsigned prec_in = pand_mask->get_precision (); + if (prec_in) + { + unsigned prec_op = and_mask.get_precision (); + if (prec_in >= prec_op) + { + if (prec_in > prec_op) + and_mask = wide_int::from (and_mask, prec_in, UNSIGNED); + and_mask &= *pand_mask; + } + else + and_mask &= wide_int::from (*pand_mask, prec_op, UNSIGNED); + } } + else if (pand_mask) +and_mask = *pand_mask; /* Turn (a ^ b) [!]= 0 into a [!]= b. */ if (xor_p && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops) @@ -8019,6 +8037,8 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, return 0; } + /* Prepare to turn compares of signed quantities with zero into + sign-bit tests, */ bool lsignbit = false, rsignbit = false; if ((lcode == LT_EXPR || lcode == GE_EXPR) && integer_zerop (lr_arg) @@ -8028,6 +8048,16 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, lsignbit = true; lcode = (lcode == LT_EXPR ? NE_EXPR : EQ_EXPR); } + else if ((lcode == LE_EXPR || lcode == GT_EXPR) + && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg)) + && TYPE_UNSIGNED (TREE_TYPE (ll_arg)) + && uniform_integer_cst_p (lr_arg) + && wi::popcount (wi::to_wide (lr_arg) + 1) == 1) +{ + ll_and_mask = ~wi::to_wide (lr_arg); + lcode = (lcode == GT_EXPR ? NE_EXPR : EQ_EXPR); + lr_arg = wide_int_to_tree (TREE_TYPE (ll_arg), ll_and_mask * 0); +} if ((rcode == LT_EXPR || rcode == GE_EXPR) && integer_zerop (rr_arg) && INTEGRAL_TYPE_P (TREE_TYPE (rl_arg)) @@ -8036,6 +8066,16 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, rsignbit = true; rcode = (rcode == LT_EXPR ? NE_EXPR : EQ_EXPR); } + else if ((rcode == LE_EXPR || rcode == GT_EXPR) + && INTEGRAL_TYPE_P (TREE_TYPE (rl_arg)) + && TYPE_UNSIGNED (TREE_TYPE (rl_arg)) + && uniform_integer_cst_p (rr_arg) + && wi::popcount (wi::to_wide (rr_arg) + 1) == 1) +{ + rl_and_mask = ~wi::to_wide (rr_arg); + rcode = (rcode == GT_EXPR ? NE_EXPR : EQ_EXPR); + rr_arg = wide_int_to_tree (TREE_TYPE (rl_arg), rl_and_mask * 0); +} /* See if the comparisons can be merged. Then get all the parameters for each side. */ diff --git a/gcc/testsuite/gcc.dg/field-merge-15.c b/gcc/testsuite/gcc.dg/field-merge-15.c new file mode 100644 index ..34641e893c92 --- /dev/null +++ b/gcc/testsuite/gcc.dg/field-merge-15.c @@ -0,0 +1,36 @@ +/* { dg-do run } */ +/* { dg-options "-O -fdump-tree-ifcombine-details" } */ + +/* Check that bitfield compares-with-zero turned into GT and LE compares with + powers-of-two minus 1 are optimized. */ + +struct s { + short a : sizeof (short) * __CHAR_BIT__ - 3; + short b : 3; + short c : 3; + short d : sizeof (short) * __CHAR_BIT__ - 3; +} __attribute__ ((aligned (4))); + +struct s p = { 15, 7, 3, 1 }; +struct s q = { 0, 0, 0, 0 }; + +void f () +{ + if (p.a || p.b || p.c || p.d) +return; + __builtin_abort (); +} + +void
[gcc(refs/users/aoliva/heads/testme)] noncontiguous ifcombine: skip marking of non-SSA_NAMEs [PR117915]
https://gcc.gnu.org/g:ae75e78f8d57aa48f03ae94c1090d14a7aa74ff8 commit ae75e78f8d57aa48f03ae94c1090d14a7aa74ff8 Author: Alexandre Oliva Date: Tue Dec 17 03:09:49 2024 -0300 noncontiguous ifcombine: skip marking of non-SSA_NAMEs [PR117915] When ifcombine_mark_ssa_name is called directly, rather than by ifcombine_mark_ssa_name_walk, we need to check that name is an SSA_NAME at the caller or in the function itself. For convenience and safety, I'm moving the checks from _walk to the implementation proper. for gcc/ChangeLog PR tree-optimization/117915 * tree-ssa-ifcombine.cc (ifcombine_mark_ssa_name): Move preconditions from... (ifcombine_mark_ssa_name_walk): ... here. for gcc/testsuite/ChangeLog PR tree-optimization/117915 * gcc.dg/pr117915.c: New. Diff: --- gcc/testsuite/gcc.dg/pr117915.c | 9 + gcc/tree-ssa-ifcombine.cc | 5 ++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/gcc.dg/pr117915.c b/gcc/testsuite/gcc.dg/pr117915.c new file mode 100644 index ..5f9f4ecf4980 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr117915.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-tree-copy-prop -fno-tree-vrp" } */ + +unsigned a; +int b, c; +int main() { + a = a & b || (c || b) | a; + return 0; +} diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc index de8db2be5572..02c2f5a29b56 100644 --- a/gcc/tree-ssa-ifcombine.cc +++ b/gcc/tree-ssa-ifcombine.cc @@ -475,7 +475,7 @@ update_profile_after_ifcombine (basic_block inner_cond_bb, static void ifcombine_mark_ssa_name (bitmap used, tree name, basic_block outer) { - if (SSA_NAME_IS_DEFAULT_DEF (name)) + if (!name || TREE_CODE (name) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (name)) return; gimple *def = SSA_NAME_DEF_STMT (name); @@ -502,8 +502,7 @@ ifcombine_mark_ssa_name_walk (tree *t, int *, void *data_) { ifcombine_mark_ssa_name_t *data = (ifcombine_mark_ssa_name_t *)data_; - if (*t && TREE_CODE (*t) == SSA_NAME) -ifcombine_mark_ssa_name (data->used, *t, data->outer); + ifcombine_mark_ssa_name (data->used, *t, data->outer); return NULL; }
[gcc/aoliva/heads/testme] (2 commits) ifcombine field merge: handle bitfield zero tests in range
The branch 'aoliva/heads/testme' was updated to point to: 30cf6dfbb6e1... ifcombine field merge: handle bitfield zero tests in range It previously pointed to: fd67db436caf... noncontiguous ifcombine: skip marking of non-SSA_NAMEs [PR1 Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- fd67db4... noncontiguous ifcombine: skip marking of non-SSA_NAMEs [PR1 Summary of changes (added commits): --- 30cf6df... ifcombine field merge: handle bitfield zero tests in range ae75e78... noncontiguous ifcombine: skip marking of non-SSA_NAMEs [PR1
[gcc r15-6297] RISC-V: Rename constraint c0* to k0*
https://gcc.gnu.org/g:1a2e0fcb857d82a7cb8909cf27a5dc833fecfa9a commit r15-6297-g1a2e0fcb857d82a7cb8909cf27a5dc833fecfa9a Author: Kito Cheng Date: Mon Dec 9 15:05:37 2024 +0800 RISC-V: Rename constraint c0* to k0* Rename those constraint since we want define other constraint start with `c`, those constraints are internal and undocumented, so it's fine to rename. gcc/ChangeLog: * config/riscv/constraints.md (c01): Rename to... (k01): ...this. (c02): Rename to... (k02): ...this. (c03): Rename to... (k03): ...this. (c04): Rename to... (k04): ...this. (c08): Rename to... (k08): ...this. * config/riscv/corev.md (riscv_cv_simd_add_h_si): Update constraints. (riscv_cv_simd_sub_h_si): Ditto. (riscv_cv_simd_cplxmul_i_si): Ditto. (riscv_cv_simd_subrotmj_si): Ditto. * config/riscv/riscv-v.cc (splat_to_scalar_move_p): Update constraints. * config/riscv/vector-iterators.md (stride_load_constraint): Update constraints. (stride_store_constraint): Ditto. Diff: --- gcc/config/riscv/constraints.md | 10 +- gcc/config/riscv/corev.md| 10 +- gcc/config/riscv/riscv-v.cc | 2 +- gcc/config/riscv/vector-iterators.md | 444 +-- 4 files changed, 233 insertions(+), 233 deletions(-) diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index eb5a0bb75c72..af8186117dbd 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -45,27 +45,27 @@ (and (match_code "const_int") (match_test "ival == 0"))) -(define_constraint "c01" +(define_constraint "k01" "Constant value 1." (and (match_code "const_int") (match_test "ival == 1"))) -(define_constraint "c02" +(define_constraint "k02" "Constant value 2" (and (match_code "const_int") (match_test "ival == 2"))) -(define_constraint "c03" +(define_constraint "k03" "Constant value 3" (and (match_code "const_int") (match_test "ival == 3"))) -(define_constraint "c04" +(define_constraint "k04" "Constant value 4" (and (match_code "const_int") (match_test "ival == 4"))) -(define_constraint "c08" +(define_constraint "k08" "Constant value 8" (and (match_code "const_int") (match_test "ival == 8"))) diff --git a/gcc/config/riscv/corev.md b/gcc/config/riscv/corev.md index e2db8f311307..02c270433017 100644 --- a/gcc/config/riscv/corev.md +++ b/gcc/config/riscv/corev.md @@ -871,7 +871,7 @@ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") (unspec:SI [(match_operand:SI 1 "register_operand" "r,r,r,r") (match_operand:SI 2 "register_operand" "r,r,r,r") - (match_operand:QI 3 "const_int2_operand" "J,c01,c02,c03")] + (match_operand:QI 3 "const_int2_operand" "J,k01,k02,k03")] UNSPEC_CV_ADD_H))] "TARGET_XCVSIMD && !TARGET_64BIT" "@ @@ -924,7 +924,7 @@ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") (unspec:SI [(match_operand:SI 1 "register_operand" "r,r,r,r") (match_operand:SI 2 "register_operand" "r,r,r,r") - (match_operand:QI 3 "const_int2_operand" "J,c01,c02,c03")] + (match_operand:QI 3 "const_int2_operand" "J,k01,k02,k03")] UNSPEC_CV_SUB_H))] "TARGET_XCVSIMD && !TARGET_64BIT" "@ @@ -2561,7 +2561,7 @@ (unspec:SI [(match_operand:SI 1 "register_operand" "r,r,r,r") (match_operand:SI 2 "register_operand" "r,r,r,r") (match_operand:SI 3 "register_operand" "0,0,0,0") - (match_operand:QI 4 "const_int2_operand" "J,c01,c02,c03")] + (match_operand:QI 4 "const_int2_operand" "J,k01,k02,k03")] UNSPEC_CV_CPLXMUL_R))] "TARGET_XCVSIMD && !TARGET_64BIT" "@ @@ -2578,7 +2578,7 @@ (unspec:SI [(match_operand:SI 1 "register_operand" "r,r,r,r") (match_operand:SI 2 "register_operand" "r,r,r,r") (match_operand:SI 3 "register_operand" "0,0,0,0") - (match_operand:QI 4 "const_int2_operand" "J,c01,c02,c03")] + (match_operand:QI 4 "const_int2_operand" "J,k01,k02,k03")] UNSPEC_CV_CPLXMUL_I))] "TARGET_XCVSIMD && !TARGET_64BIT" "@ @@ -2604,7 +2604,7 @@ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") (unspec:SI [(match_operand:SI 1 "register_operand" "r,r,r,r") (match_operand:SI 2 "register_operand" "r,r,r,r") - (match_operand:QI 3 "const_int2_operand" "J,c01,c02,c03")] + (match_operand:QI 3 "const_int2_operand" "J,k01,k02,k03")] UNSPEC_CV_SUBROTMJ))] "TARGET_XCVSIMD && !TARGET_64BIT"
[gcc r15-6298] RISC-V: Add cr and cf constraint
https://gcc.gnu.org/g:46888571d242cf5623b7b0b74bb4490572f81cc9 commit r15-6298-g46888571d242cf5623b7b0b74bb4490572f81cc9 Author: Kito Cheng Date: Wed Nov 13 17:54:16 2024 +0800 RISC-V: Add cr and cf constraint gcc/ChangeLog: * config/riscv/constraints.md (cr): New. (cf): New. * config/riscv/riscv.h (reg_class): Add RVC_GR_REGS and RVC_FP_REGS. (REG_CLASS_NAMES): Ditto. (REG_CLASS_CONTENTS): Ditto. * doc/md.texi: Document cr and cf constraint. * config/riscv/riscv.cc (riscv_regno_to_class): Update FP_REGS to RVC_FP_REGS since it smaller set. (riscv_secondary_memory_needed): Handle RVC_FP_REGS. (riscv_register_move_cost): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/constraint-cf-zfinx.c: New. * gcc.target/riscv/constraint-cf.c: New. * gcc.target/riscv/constraint-cr.c: New. Diff: --- gcc/config/riscv/constraints.md| 6 + gcc/config/riscv/riscv.cc | 28 +- gcc/config/riscv/riscv.h | 6 + gcc/doc/md.texi| 7 ++ .../gcc.target/riscv/constraint-cf-zfinx.c | 14 +++ gcc/testsuite/gcc.target/riscv/constraint-cf.c | 14 +++ gcc/testsuite/gcc.target/riscv/constraint-cr.c | 13 ++ 7 files changed, 77 insertions(+), 11 deletions(-) diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index af8186117dbd..2dce9832219b 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -33,6 +33,12 @@ (define_register_constraint "l" "JALR_REGS" "@internal") +(define_register_constraint "cr" "RVC_GR_REGS" + "RVC general purpose register (x8-x15).") + +(define_register_constraint "cf" "TARGET_HARD_FLOAT ? RVC_FP_REGS : (TARGET_ZFINX ? RVC_GR_REGS : NO_REGS)" + "RVC floating-point registers (f8-f15), if available, reuse GPR as FPR when use zfinx.") + ;; General constraints (define_constraint "I" diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index aa8a4562d9af..6492913d8f80 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -350,14 +350,14 @@ const enum reg_class riscv_regno_to_class[FIRST_PSEUDO_REGISTER] = { JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS, SIBCALL_REGS,SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS, - FP_REGS, FP_REGS,FP_REGS,FP_REGS, - FP_REGS, FP_REGS,FP_REGS,FP_REGS, - FP_REGS, FP_REGS,FP_REGS,FP_REGS, - FP_REGS, FP_REGS,FP_REGS,FP_REGS, - FP_REGS, FP_REGS,FP_REGS,FP_REGS, - FP_REGS, FP_REGS,FP_REGS,FP_REGS, - FP_REGS, FP_REGS,FP_REGS,FP_REGS, - FP_REGS, FP_REGS,FP_REGS,FP_REGS, + RVC_FP_REGS, RVC_FP_REGS,RVC_FP_REGS,RVC_FP_REGS, + RVC_FP_REGS, RVC_FP_REGS,RVC_FP_REGS,RVC_FP_REGS, + RVC_FP_REGS, RVC_FP_REGS,RVC_FP_REGS,RVC_FP_REGS, + RVC_FP_REGS, RVC_FP_REGS,RVC_FP_REGS,RVC_FP_REGS, + RVC_FP_REGS, RVC_FP_REGS,RVC_FP_REGS,RVC_FP_REGS, + RVC_FP_REGS, RVC_FP_REGS,RVC_FP_REGS,RVC_FP_REGS, + RVC_FP_REGS, RVC_FP_REGS,RVC_FP_REGS,RVC_FP_REGS, + RVC_FP_REGS, RVC_FP_REGS,RVC_FP_REGS,RVC_FP_REGS, FRAME_REGS, FRAME_REGS, NO_REGS,NO_REGS, NO_REGS, NO_REGS,NO_REGS,NO_REGS, NO_REGS, NO_REGS,NO_REGS,NO_REGS, @@ -9500,9 +9500,11 @@ static bool riscv_secondary_memory_needed (machine_mode mode, reg_class_t class1, reg_class_t class2) { + bool class1_is_fpr = class1 == FP_REGS || class1 == RVC_FP_REGS; + bool class2_is_fpr = class2 == FP_REGS || class2 == RVC_FP_REGS; return (!riscv_v_ext_mode_p (mode) && GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD - && (class1 == FP_REGS) != (class2 == FP_REGS) + && (class1_is_fpr != class2_is_fpr) && !TARGET_XTHEADFMV && !TARGET_ZFA); } @@ -9513,8 +9515,12 @@ int riscv_register_move_cost (machine_mode mode, reg_class_t from, reg_class_t to) { - if ((from == FP_REGS && to == GR_REGS) || - (from == GR_REGS && to == FP_REGS)) + bool from_is_fpr = from == FP_REGS || from == RVC_FP_REGS; + bool from_is_gpr = from == GR_REGS || from == RVC_GR_REGS; + bool to_is_fpr = to == FP_REGS || to == RVC_FP_REGS; + bool to_is_gpr = to == GR_REGS || to == RVC_GR_REGS; + if ((from_is_fpr && to == to_is_gpr) || + (from_is_gpr && to_is_fpr)) return tune_param->fmv_cost; if (from == V_REGS) diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 09de74667a90..aacb557248f9 100644 --- a/g
[gcc r15-6299] RISC-V: Rename internal operand modifier N to n
https://gcc.gnu.org/g:192790e994c9e15949e694e0a52010001b291611 commit r15-6299-g192790e994c9e15949e694e0a52010001b291611 Author: Kito Cheng Date: Thu Nov 14 16:41:52 2024 +0800 RISC-V: Rename internal operand modifier N to n Here is a purposal that using N for printing register encoding number, so let rename the existing internal operand modifier `N` to `n`. gcc/ChangeLog: * config/riscv/corev.md (*cv_branch): Update modifier. (*branch): Ditto. * config/riscv/riscv.cc (riscv_print_operand): Update modifier. * config/riscv/riscv.md (*branch): Update modifier. Diff: --- gcc/config/riscv/corev.md | 4 ++-- gcc/config/riscv/riscv.cc | 4 ++-- gcc/config/riscv/riscv.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gcc/config/riscv/corev.md b/gcc/config/riscv/corev.md index 02c270433017..3c0e9cecdfba 100644 --- a/gcc/config/riscv/corev.md +++ b/gcc/config/riscv/corev.md @@ -2627,7 +2627,7 @@ "TARGET_XCVBI" { if (get_attr_length (insn) == 12) -return "cv.b%N1\t%2,%z3,1f; jump\t%l0,ra; 1:"; +return "cv.b%n1\t%2,%z3,1f; jump\t%l0,ra; 1:"; return "cv.b%C1imm\t%2,%3,%0"; } @@ -2645,7 +2645,7 @@ "TARGET_XCVBI" { if (get_attr_length (insn) == 12) -return "b%N1\t%2,%z3,1f; jump\t%l0,ra; 1:"; +return "b%n1\t%2,%z3,1f; jump\t%l0,ra; 1:"; return "b%C1\t%2,%z3,%l0"; } diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 6492913d8f80..db2329c03193 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -6823,7 +6823,7 @@ riscv_asm_output_opcode (FILE *asm_out_file, const char *p) any outermost HIGH. 'R' Print the low-part relocation associated with OP. 'C' Print the integer branch condition for comparison OP. - 'N' Print the inverse of the integer branch condition for comparison OP. + 'n' Print the inverse of the integer branch condition for comparison OP. 'A' Print the atomic operation suffix for memory model OP. 'I' Print the LR suffix for memory model OP. 'J' Print the SC suffix for memory model OP. @@ -6981,7 +6981,7 @@ riscv_print_operand (FILE *file, rtx op, int letter) fputs (GET_RTX_NAME (code), file); break; -case 'N': +case 'n': /* The RTL names match the instruction names. */ fputs (GET_RTX_NAME (reverse_condition (code)), file); break; diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 3a4cd1d93a0f..1eec51c117a7 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3215,7 +3215,7 @@ "!TARGET_XCVBI" { if (get_attr_length (insn) == 12) -return "b%N1\t%2,%z3,1f; jump\t%l0,ra; 1:"; +return "b%n1\t%2,%z3,1f; jump\t%l0,ra; 1:"; return "b%C1\t%2,%z3,%l0"; }
[gcc r15-6301] RISC-V: Add new constraint R for register even-odd pairs
https://gcc.gnu.org/g:fcbb8456a58ba073d4d5b10fcb9057b6e9a100db commit r15-6301-gfcbb8456a58ba073d4d5b10fcb9057b6e9a100db Author: Kito Cheng Date: Mon Dec 9 14:55:20 2024 +0800 RISC-V: Add new constraint R for register even-odd pairs Although this constraint is not currently used for any instructions, it is very useful for custom instructions. Additionally, some new standard extensions (not yet upstream), such as `Zilsd` and `Zclsd`, are potential users of this constraint. Therefore, I believe there is sufficient justification to add it now. gcc/ChangeLog: * config/riscv/constraints.md (R): New constraint. * doc/md.texi: Document new constraint `R`. gcc/testsuite/ChangeLog: * gcc.target/riscv/constraint-R.c: New. Diff: --- gcc/config/riscv/constraints.md | 4 gcc/doc/md.texi | 3 +++ gcc/testsuite/gcc.target/riscv/constraint-R.c | 23 +++ 3 files changed, 30 insertions(+) diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index 2dce9832219b..ebb71000d123 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -28,6 +28,10 @@ (define_register_constraint "j" "SIBCALL_REGS" "@internal") +(define_register_constraint "R" "GR_REGS" + "Even-odd general purpose register pair." + "regno % 2 == 0") + ;; Avoid using register t0 for JALR's argument, because for some ;; microarchitectures that is a return-address stack hint. (define_register_constraint "l" "JALR_REGS" diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index d5e5367e4efe..32faede817ad 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -3667,6 +3667,9 @@ RVC general purpose register (x8-x15). RVC floating-point registers (f8-f15), if available, reuse GPR as FPR when use zfinx. +@item R +Even-odd general purpose register pair. + @end table @item RX---@file{config/rx/constraints.md} diff --git a/gcc/testsuite/gcc.target/riscv/constraint-R.c b/gcc/testsuite/gcc.target/riscv/constraint-R.c new file mode 100644 index ..cb13d8a1f38a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/constraint-R.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ +/* { dg-final { check-function-bodies "**" "" } } */ +/* { dg-additional-options "-std=gnu99" } */ + +void foo(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int m0, int m1) { +/* +** foo: +** ... +** addi t1, (a[0246]|s[02468]|t[02]), 1 +** ... +*/ +__asm__ volatile("addi t1, %0, 1" : : "R" (a1) : "memory"); +} +void foo2(int a0, long long a1a2) { +/* +** foo2: +** ... +** addi t1, (a[0246]|s[02468]|t[02]), 1 +** ... +*/ +__asm__ volatile("addi t1, %0, 1" : : "R" (a1a2) : "memory"); +}
[gcc r15-6300] RISC-V: Implment N modifier for printing the register number rather than the register name
https://gcc.gnu.org/g:2a22db391d1819f6068aa43e63632b350a0b4bec commit r15-6300-g2a22db391d1819f6068aa43e63632b350a0b4bec Author: Kito Cheng Date: Thu Nov 14 17:24:45 2024 +0800 RISC-V: Implment N modifier for printing the register number rather than the register name The modifier `N`, to print the raw encoding of a register. This is used when using `.insn , `, where the user wants to pass a value to the instruction in a known register, but where the instruction doesn't follow the existing instruction formats, so the assembly parser is not expecting a register name, just a raw integer. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_print_operand): Add N. * doc/extend.texi: Document for N, gcc/testsuite/ChangeLog: * gcc.target/riscv/modifier-N-fpr.c: New. * gcc.target/riscv/modifier-N-vr.c: New. * gcc.target/riscv/modifier-N.c: New. Diff: --- gcc/config/riscv/riscv.cc | 23 +++ gcc/doc/extend.texi | 1 + gcc/testsuite/gcc.target/riscv/modifier-N-fpr.c | 16 gcc/testsuite/gcc.target/riscv/modifier-N-vr.c | 18 ++ gcc/testsuite/gcc.target/riscv/modifier-N.c | 16 5 files changed, 74 insertions(+) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index db2329c03193..ed75c653481f 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -6833,6 +6833,7 @@ riscv_asm_output_opcode (FILE *asm_out_file, const char *p) 'S' Print shift-index of single-bit mask OP. 'T' Print shift-index of inverted single-bit mask OP. '~' Print w if TARGET_64BIT is true; otherwise not print anything. + 'N' Print register encoding as integer (0-31). Note please keep this list and the list in riscv.md in sync. */ @@ -7079,6 +7080,28 @@ riscv_print_operand (FILE *file, rtx op, int letter) output_addr_const (file, newop); break; } +case 'N': + { + if (!REG_P(op)) + { + output_operand_lossage ("modifier 'N' require register operand"); + break; + } + + unsigned regno = REGNO (op); + unsigned offset = 0; + if (IN_RANGE (regno, GP_REG_FIRST, GP_REG_LAST)) + offset = GP_REG_FIRST; + else if (IN_RANGE (regno, FP_REG_FIRST, FP_REG_LAST)) + offset = FP_REG_FIRST; + else if (IN_RANGE (regno, V_REG_FIRST, V_REG_LAST)) + offset = V_REG_FIRST; + else + output_operand_lossage ("invalid register number for 'N' modifie"); + + asm_fprintf (file, "%u", (regno - offset)); + break; + } default: switch (code) { diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index ebd970155f78..d991aa0a5081 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -12594,6 +12594,7 @@ The list below describes the supported modifiers and their effects for RISC-V. @headitem Modifier @tab Description @item @code{z} @tab Print ''@code{zero}'' instead of 0 if the operand is an immediate with a value of zero. @item @code{i} @tab Print the character ''@code{i}'' if the operand is an immediate. +@item @code{N} @tab Print the register encoding as integer (0 - 31). @end multitable @anchor{shOperandmodifiers} diff --git a/gcc/testsuite/gcc.target/riscv/modifier-N-fpr.c b/gcc/testsuite/gcc.target/riscv/modifier-N-fpr.c new file mode 100644 index ..42590e00c0d4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/modifier-N-fpr.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64if -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +void foo() { +/* +** foo: +** ... +** fadd.s\s*ft0,\s*8,\s*9 +** ... +*/ + register float fs0 __asm__ ("fs0"); + register float fs1 __asm__ ("fs1"); + __asm__ volatile("fadd.s ft0, %N0, %N1" : : "f" (fs0), "f" (fs1) : "memory"); +} diff --git a/gcc/testsuite/gcc.target/riscv/modifier-N-vr.c b/gcc/testsuite/gcc.target/riscv/modifier-N-vr.c new file mode 100644 index ..ea591b021386 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/modifier-N-vr.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gv -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#pragma riscv intrinsic "vector" + +void foo() { +/* +** foo: +** ... +** vadd.vv\s*v0,\s*1,\s*2 +** ... +*/ + register vint32m1_t v1 __asm__ ("v1"); + register vint32m1_t v2 __asm__ ("v2"); + __asm__ volatile("vadd.vv v0, %N0, %N1" : : "vr" (v1), "vr" (v2) : "memory"); +} diff --git a/gcc/testsuite/gcc.target/riscv/modifier-N.c b/gcc/testsuite/gcc.target/riscv/modifier-N.c new file mode 100644 index ..fef281611efb --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/modifie
[gcc r15-6302] testsuite: arm: Add -mtune to all arm_cpu_* effective targets
https://gcc.gnu.org/g:423ee61fdd91e196726afeb38c907b23404aea71 commit r15-6302-g423ee61fdd91e196726afeb38c907b23404aea71 Author: Torbjörn SVENSSON Date: Mon Dec 16 14:47:40 2024 +0100 testsuite: arm: Add -mtune to all arm_cpu_* effective targets Fixes Linaro CI reported regression on r15-6164-gbdf75257aad2 in https://linaro.atlassian.net/browse/GNU-1463. gcc/testsuite/ChangeLog: * lib/target-supports.exp: Added corresponding -mtune= option for each fo the arm_cpu_* effective targets. Signed-off-by: Torbjörn SVENSSON Diff: --- gcc/testsuite/lib/target-supports.exp | 27 +++ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index fe2970e024bf..a16e9534ccdd 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -5955,21 +5955,24 @@ foreach { armfunc armflag armdefs } { #/* { dg-add-options arm_cpu_xscale } */ # /* { dg-require-effective-target arm_xscale_multilib } */ +# NOTE: -mcpu does not override -mtune, so to ensure the tuning is consistent +# for tests using these flags all entries should set -mcpu and -mtune explicitly + # This table should only be used to set -mcpu= (and associated # flags). See above for setting -march=. foreach { armfunc armflag armdefs } { - xscale_arm "-mcpu=xscale -mfloat-abi=soft -marm" "__XSCALE__ && !__thumb__" - cortex_a57 "-mcpu=cortex-a57" __ARM_ARCH_8A__ - cortex_m0 "-mcpu=cortex-m0 -mfloat-abi=soft -mthumb" "__ARM_ARCH_6M__ && __thumb__" - cortex_m0_small "-mcpu=cortex-m0.small-multiply -mfloat-abi=soft -mthumb" "__ARM_ARCH_6M__ && __thumb__" - cortex_m0plus_small "-mcpu=cortex-m0plus.small-multiply -mfloat-abi=soft -mthumb" "__ARM_ARCH_6M__ && __thumb__" - cortex_m1_small "-mcpu=cortex-m1.small-multiply -mfloat-abi=soft -mthumb" "__ARM_ARCH_6M__ && __thumb__" - cortex_m3 "-mcpu=cortex-m3 -mfloat-abi=soft -mthumb" "__ARM_ARCH_7M__" - cortex_m4 "-mcpu=cortex-m4 -mfpu=auto -mthumb" "__ARM_ARCH_7EM__" - cortex_m4_hard "-mcpu=cortex-m4 -mfpu=auto -mfloat-abi=hard -mthumb" "__ARM_ARCH_7EM__" - cortex_m7 "-mcpu=cortex-m7 -mfpu=auto -mthumb" "__ARM_ARCH_7EM__" - cortex_m23 "-mcpu=cortex-m23 -mfloat-abi=soft -mthumb" "__ARM_ARCH_8M_BASE__ && __thumb__" - cortex_m55 "-mcpu=cortex-m55 -mfpu=auto -mthumb" "__ARM_ARCH_8M_MAIN__ && __thumb__" + xscale_arm "-mcpu=xscale -mtune=xscale -mfloat-abi=soft -marm" "__XSCALE__ && !__thumb__" + cortex_a57 "-mcpu=cortex-a57 -mtune=cortex-a57" __ARM_ARCH_8A__ + cortex_m0 "-mcpu=cortex-m0 -mtune=cortex-m0 -mfloat-abi=soft -mthumb" "__ARM_ARCH_6M__ && __thumb__" + cortex_m0_small "-mcpu=cortex-m0.small-multiply -mtune=cortex-m0.small-multiply -mfloat-abi=soft -mthumb" "__ARM_ARCH_6M__ && __thumb__" + cortex_m0plus_small "-mcpu=cortex-m0plus.small-multiply -mtune=cortex-m0plus.small-multiply -mfloat-abi=soft -mthumb" "__ARM_ARCH_6M__ && __thumb__" + cortex_m1_small "-mcpu=cortex-m1.small-multiply -mtune=cortex-m1.small-multiply -mfloat-abi=soft -mthumb" "__ARM_ARCH_6M__ && __thumb__" + cortex_m3 "-mcpu=cortex-m3 -mtune=cortex-m3 -mfloat-abi=soft -mthumb" "__ARM_ARCH_7M__" + cortex_m4 "-mcpu=cortex-m4 -mtune=cortex-m4 -mfpu=auto -mthumb" "__ARM_ARCH_7EM__" + cortex_m4_hard "-mcpu=cortex-m4 -mtune=cortex-m4 -mfpu=auto -mfloat-abi=hard -mthumb" "__ARM_ARCH_7EM__" + cortex_m7 "-mcpu=cortex-m7 -mtune=cortex-m7 -mfpu=auto -mthumb" "__ARM_ARCH_7EM__" + cortex_m23 "-mcpu=cortex-m23 -mtune=cortex-m23 -mfloat-abi=soft -mthumb" "__ARM_ARCH_8M_BASE__ && __thumb__" + cortex_m55 "-mcpu=cortex-m55 -mtune=cortex-m55 -mfpu=auto -mthumb" "__ARM_ARCH_8M_MAIN__ && __thumb__" } { eval [string map [list FUNC $armfunc FLAG $armflag DEFS $armdefs ] { proc check_effective_target_arm_cpu_FUNC_ok { } {
[gcc r15-6303] [PATCH v2 1/2] RISC-V: Document thead-c906, xiangshan-nanhu, and generic-ooo
https://gcc.gnu.org/g:5601c411f4ffdb8bbfec09a58234ab2ebc5de986 commit r15-6303-g5601c411f4ffdb8bbfec09a58234ab2ebc5de986 Author: Anton Blanchard Date: Tue Dec 17 07:30:55 2024 -0700 [PATCH v2 1/2] RISC-V: Document thead-c906, xiangshan-nanhu, and generic-ooo gcc/ChangeLog * doc/invoke.texi (RISC-V): Add thead-c906, xiangshan-nanhu to -mcpu, add generic-ooo and remove thead-c906 from -mtune. Diff: --- gcc/doc/invoke.texi | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 0fdf85015857..017bb8075ac5 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -30981,17 +30981,18 @@ Permissible values for this option are: @samp{sifive-e20}, @samp{sifive-e21}, @samp{sifive-e24}, @samp{sifive-e31}, @samp{sifive-e34}, @samp{sifive-e76}, @samp{sifive-s21}, @samp{sifive-s51}, @samp{sifive-s54}, @samp{sifive-s76}, @samp{sifive-u54}, @samp{sifive-u74}, @samp{sifive-x280}, @samp{sifive-xp450}, -@samp{sifive-x670}. +@samp{sifive-x670}, @samp{thead-c906}, @samp{xiangshan-nanhu}. Note that @option{-mcpu} does not override @option{-march} or @option{-mtune}. @opindex mtune @item -mtune=@var{processor-string} Optimize the output for the given processor, specified by microarchitecture or -particular CPU name. Permissible values for this option are: @samp{rocket}, -@samp{sifive-3-series}, @samp{sifive-5-series}, @samp{sifive-7-series}, -@samp{thead-c906}, @samp{size}, @samp{sifive-p400-series}, -@samp{sifive-p600-series}, and all valid options for @option{-mcpu=}. +particular CPU name. Permissible values for this option are: +@samp{generic-ooo}, @samp{rocket}, @samp{sifive-3-series}, +@samp{sifive-5-series}, @samp{sifive-7-series}, @samp{size}, +@samp{sifive-p400-series}, @samp{sifive-p600-series}, and all valid options for +@option{-mcpu=}. When @option{-mtune=} is not specified, use the setting from @option{-mcpu}, the default is @samp{rocket} if both are not specified.
[gcc r15-6304] [PATCH v2 2/2] RISC-V: Add Tenstorrent Ascalon 8 wide architecture
https://gcc.gnu.org/g:4aa01ecc5c1389d1cdf5721b936993ba17b96178 commit r15-6304-g4aa01ecc5c1389d1cdf5721b936993ba17b96178 Author: Anton Blanchard Date: Tue Dec 17 07:34:20 2024 -0700 [PATCH v2 2/2] RISC-V: Add Tenstorrent Ascalon 8 wide architecture This adds the Tenstorrent Ascalon 8 wide architecture (tt-ascalon-d8) to the list of known cores. gcc/ChangeLog: * config/riscv/riscv-cores.def: Add tt-ascalon-d8. * config/riscv/riscv.cc (tt_ascalon_d8_tune_info): New. * doc/invoke.texi (RISC-V): Add tt-ascalon-d8 to -mcpu. gcc/testsuite/ChangeLog: * gcc.target/riscv/mcpu-tt-ascalon-d8.c: New test. Diff: --- gcc/config/riscv/riscv-cores.def | 8 +++ gcc/config/riscv/riscv.cc | 22 +++ gcc/doc/invoke.texi| 3 +- .../gcc.target/riscv/mcpu-tt-ascalon-d8.c | 76 ++ 4 files changed, 108 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def index 2f5efe3be86a..4fd09e653d26 100644 --- a/gcc/config/riscv/riscv-cores.def +++ b/gcc/config/riscv/riscv-cores.def @@ -39,6 +39,7 @@ RISCV_TUNE("sifive-5-series", generic, rocket_tune_info) RISCV_TUNE("sifive-7-series", sifive_7, sifive_7_tune_info) RISCV_TUNE("sifive-p400-series", sifive_p400, sifive_p400_tune_info) RISCV_TUNE("sifive-p600-series", sifive_p600, sifive_p600_tune_info) +RISCV_TUNE("tt-ascalon-d8", generic_ooo, tt_ascalon_d8_tune_info) RISCV_TUNE("thead-c906", generic, thead_c906_tune_info) RISCV_TUNE("xiangshan-nanhu", xiangshan, xiangshan_nanhu_tune_info) RISCV_TUNE("generic-ooo", generic_ooo, generic_ooo_tune_info) @@ -92,6 +93,13 @@ RISCV_CORE("thead-c906", "rv64imafdc_xtheadba_xtheadbb_xtheadbs_xtheadcmo_" "xtheadmemidx_xtheadmempair_xtheadsync", "thead-c906") +RISCV_CORE("tt-ascalon-d8", "rv64imafdcv_zic64b_zicbom_zicbop_zicboz_" + "ziccamoa_ziccif_zicclsm_ziccrse_zicond_zicsr_" + "zifencei_zihintntl_zihintpause_zimop_za64rs_" + "zawrs_zfa_zfbfmin_zfh_zcb_zcmop_zba_zbb_zbs_" + "zvbb_zvbc_zvfbfwma_zvfh_zvkng_zvl256b", + "tt-ascalon-d8") + RISCV_CORE("xiangshan-nanhu", "rv64imafdc_zba_zbb_zbc_zbs_" "zbkb_zbkc_zbkx_zknd_zkne_zknh_zksed_zksh_" "svinval_zicbom_zicboz", diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index ed75c653481f..4f1f9defc801 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -598,6 +598,28 @@ static const struct riscv_tune_param generic_ooo_tune_info = { NULL,/* loop_align */ }; +/* Costs to use when optimizing for Tenstorrent Ascalon 8 wide. */ +static const struct riscv_tune_param tt_ascalon_d8_tune_info = { + {COSTS_N_INSNS (2), COSTS_N_INSNS (2)}, /* fp_add */ + {COSTS_N_INSNS (3), COSTS_N_INSNS (3)}, /* fp_mul */ + {COSTS_N_INSNS (9), COSTS_N_INSNS (16)}, /* fp_div */ + {COSTS_N_INSNS (3), COSTS_N_INSNS (3)}, /* int_mul */ + {COSTS_N_INSNS (13), COSTS_N_INSNS (13)},/* int_div */ + 8, /* issue_rate */ + 3, /* branch_cost */ + 4, /* memory_cost */ + 4, /* fmv_cost */ + false, /* slow_unaligned_access */ + true,/* vector_unaligned_access */ + true,/* use_divmod_expansion */ + true,/* overlap_op_by_pieces */ + RISCV_FUSE_NOTHING, /* fusible_ops */ + &generic_vector_cost,/* vector cost */ + NULL,/* function_align */ + NULL,/* jump_align */ + NULL,/* loop_align */ +}; + /* Costs to use when optimizing for size. */ static const struct riscv_tune_param optimize_size_tune_info = { {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_add */ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 017bb8075ac5..749f30e330f4 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -30981,7 +30981,8 @@ Permissible values for this option are: @samp{sifive-e20}, @samp{sifive-e21}, @samp{sifive-e24}, @samp{sifive-e31}, @samp{sifive-e34}, @samp{sifive-e76}, @samp{sifive-s21}, @samp{sifive-s51}, @samp{sifive-s54}, @samp{sifive-s76}, @samp{sifive-u54}, @samp{sifive-u74}, @samp{sifive-x280}, @samp{sifive-xp450}, -@sam
[gcc r15-6293] c++: Diagnose earlier non-static data members with cv containing class type [PR116108]
https://gcc.gnu.org/g:88bfee560681d8248b89f130ada249e35ee2e344 commit r15-6293-g88bfee560681d8248b89f130ada249e35ee2e344 Author: Jakub Jelinek Date: Tue Dec 17 10:13:24 2024 +0100 c++: Diagnose earlier non-static data members with cv containing class type [PR116108] In r10-6457 aka PR92593 fix a check has been added to reject earlier non-static data members with current_class_type in templates, as the deduction then can result in endless recursion in reshape_init. It fixed the template struct S { S s = 1; }; S t{2}; crashes, but as the following testcase shows, didn't catch when there are cv qualifiers on the non-static data member. Fixed by using TYPE_MAIN_VARIANT. 2024-12-17 Jakub Jelinek PR c++/116108 gcc/cp/ * decl.cc (grokdeclarator): Pass TYYPE_MAIN_VARIANT (type) rather than type to same_type_p when checking if the non-static data member doesn't have current class type. gcc/testsuite/ * g++.dg/cpp1z/class-deduction117.C: New test. Diff: --- gcc/cp/decl.cc | 3 ++- gcc/testsuite/g++.dg/cpp1z/class-deduction117.C | 7 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index a1b9957a9bed..5bd0e2195615 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -15131,7 +15131,8 @@ grokdeclarator (const cp_declarator *declarator, } else if (!staticp && ((current_class_type - && same_type_p (type, current_class_type)) + && same_type_p (TYPE_MAIN_VARIANT (type), + current_class_type)) || (!dependent_type_p (type) && !COMPLETE_TYPE_P (complete_type (type)) && (!complete_or_array_type_p (type) diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction117.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction117.C new file mode 100644 index ..8ab91018377f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction117.C @@ -0,0 +1,7 @@ +// PR c++/116108 +// { dg-do compile { target c++11 } } +template +struct S { const S s = 1; }; // { dg-error "field 's' has incomplete type 'const S'" } +S t{2};// { dg-error "invalid use of template-name 'S' without an argument list" "" { target c++14_down } } +// { dg-error "class template argument deduction failed" "" { target c++17 } .-1 } +// { dg-error "no matching function for call to 'S\\\(int\\\)'" "" { target c++17 } .-2 }
[gcc(refs/users/aoliva/heads/testme)] ifcombine field merge: handle masks with sign extensions
https://gcc.gnu.org/g:ae42ade2c98f31a4095e78267e00aaa591b46f01 commit ae42ade2c98f31a4095e78267e00aaa591b46f01 Author: Alexandre Oliva Date: Tue Dec 17 22:19:07 2024 -0300 ifcombine field merge: handle masks with sign extensions When a loaded field is sign extended, masked and compared, we used to drop from the mask the bits past the original field width, which is not correct. Take note of the fact that the mask covered copies of the sign bit, before clipping it, and arrange to test the sign bit if we're comparing with zero. Punt in other cases. for gcc/ChangeLog * gimple-fold.cc (decode_field_reference): Add psignbit parameter. Set it if the mask references sign-extending bits. (fold_truth_andor_for_ifcombine): Adjust calls with new variables. Swap them along with other r?_* variables. Handle extended sign bit compares with zero. for gcc/testsuite/ChangeLog * gcc.dg/field-merge-16.c: New. Diff: --- gcc/gimple-fold.cc| 69 ++- gcc/testsuite/gcc.dg/field-merge-16.c | 66 + gcc/tree-ssa-ifcombine.cc | 5 ++- 3 files changed, 128 insertions(+), 12 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 856ee5369a8c..b84269d6b417 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7514,6 +7514,9 @@ gimple_binop_def_p (enum tree_code code, tree t, tree op[2]) is initially set to a mask with nonzero precision, that mask is combined with the found mask, or adjusted in precision to match. + *PSIGNBIT is set to TRUE if, before clipping to *PBITSIZE, the mask + encompassed bits that corresponded to extensions of the sign bit. + *XOR_P is to be FALSE if EXP might be a XOR used in a compare, in which case, if XOR_CMP_OP is a zero constant, it will be overridden with *PEXP, *XOR_P will be set to TRUE, and the left-hand operand of the XOR will be @@ -7533,7 +7536,8 @@ static tree decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, HOST_WIDE_INT *pbitpos, bool *punsignedp, bool *preversep, bool *pvolatilep, - wide_int *pand_mask, bool *xor_p, tree *xor_cmp_op, + wide_int *pand_mask, bool *psignbit, + bool *xor_p, tree *xor_cmp_op, gimple **load, location_t loc[4]) { tree exp = *pexp; @@ -7545,6 +7549,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, machine_mode mode; *load = NULL; + *psignbit = false; /* All the optimizations using this function assume integer fields. There are problems with FP fields since the type_for_size call @@ -7708,12 +7713,23 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, if (outer_type && *pbitsize == TYPE_PRECISION (outer_type)) *punsignedp = TYPE_UNSIGNED (outer_type); - /* Make the mask the expected width. */ - if (and_mask.get_precision () != 0) -and_mask = wide_int::from (and_mask, *pbitsize, UNSIGNED); - if (pand_mask) -*pand_mask = and_mask; +{ + /* Make the mask the expected width. */ + if (and_mask.get_precision () != 0) + { + /* If the AND_MASK encompasses bits that would be extensions of +the sign bit, set *PSIGNBIT. */ + if (!unsignedp + && and_mask.get_precision () > *pbitsize + && (and_mask + & wi::mask (*pbitsize, true, and_mask.get_precision ())) != 0) + *psignbit = true; + and_mask = wide_int::from (and_mask, *pbitsize, UNSIGNED); + } + + *pand_mask = and_mask; +} return inner; } @@ -7995,6 +8011,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, HOST_WIDE_INT rnbitsize, rnbitpos, rnprec; bool ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp; bool ll_reversep, lr_reversep, rl_reversep, rr_reversep; + bool ll_signbit, lr_signbit, rl_signbit, rr_signbit; scalar_int_mode lnmode, lnmode2, rnmode; wide_int ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask; wide_int l_const, r_const; @@ -8114,19 +8131,19 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, bool l_xor = false, r_xor = false; ll_inner = decode_field_reference (&ll_arg, &ll_bitsize, &ll_bitpos, &ll_unsignedp, &ll_reversep, &volatilep, -&ll_and_mask, &l_xor, &lr_arg, +&ll_and_mask, &ll_signbit, &l_xor, &lr_arg, &ll_load, ll_loc); lr_inner = decode_field_reference (&lr_arg, &lr_bitsize, &lr_bitpos, &lr_unsignedp, &lr_reversep, &volatilep, -&lr_and_mask, &l_xor, 0
[gcc/aoliva/heads/testme] ifcombine field merge: handle bitfield zero tests in range
The branch 'aoliva/heads/testme' was updated to point to: 85677ef350e4... ifcombine field merge: handle bitfield zero tests in range It previously pointed to: 30cf6dfbb6e1... ifcombine field merge: handle bitfield zero tests in range Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- 30cf6df... ifcombine field merge: handle bitfield zero tests in range Summary of changes (added commits): --- 85677ef... ifcombine field merge: handle bitfield zero tests in range
[gcc(refs/users/aoliva/heads/testme)] ifcombine field merge: handle bitfield zero tests in range tests
https://gcc.gnu.org/g:85677ef350e44e28a565caaa810bd5f11056bd7a commit 85677ef350e44e28a565caaa810bd5f11056bd7a Author: Alexandre Oliva Date: Tue Dec 17 11:22:23 2024 -0300 ifcombine field merge: handle bitfield zero tests in range tests Some bitfield compares with zero are optimized to range tests, so instead of X & ~(Bit - 1) != 0 what reaches ifcombine is X > (Bit - 1), where Bit is a power of two and X is unsigned. This patch recognizes this optimized form of masked compares, and attempts to merge them like masked compares, which enables some more field merging that a folder version of fold_truth_andor used to handle without additional effort. I haven't seen X & ~(Bit - 1) == 0 become X <= (Bit - 1), or X < Bit for that matter, but it was easy enough to handle the former symmetrically to the above. The latter was also easy enough, and so was its symmetric, X >= Bit, that is handled like X & ~(Bit - 1) != 0. The second added testcase is only vaguely related with this new feature, but I realized it was something that wasn't covered in field-merge tests yet. for gcc/ChangeLog * gimple-fold.cc (decode_field_reference): Accept incoming mask. (fold_truth_andor_for_ifcombine): Handle some compares with powers of two, minus 1 or 0, like masked compares with zero. for gcc/testsuite/ChangeLog * gcc.dg/field-merge-15.c: New. * gcc.dg/field-merge-16.c: New. Diff: --- gcc/gimple-fold.cc| 71 +-- gcc/testsuite/gcc.dg/field-merge-15.c | 36 ++ gcc/testsuite/gcc.dg/field-merge-16.c | 43 + 3 files changed, 147 insertions(+), 3 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 06913d57f8ae..856ee5369a8c 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7509,8 +7509,10 @@ gimple_binop_def_p (enum tree_code code, tree t, tree op[2]) *PREVERSEP is set to the storage order of the field. - *PAND_MASK is set to the mask found in a BIT_AND_EXPR, if any. - If PAND_MASK *is NULL, BIT_AND_EXPR is not recognized. + *PAND_MASK is set to the mask found in a BIT_AND_EXPR, if any. If + PAND_MASK *is NULL, BIT_AND_EXPR is not recognized. If *PAND_MASK + is initially set to a mask with nonzero precision, that mask is + combined with the found mask, or adjusted in precision to match. *XOR_P is to be FALSE if EXP might be a XOR used in a compare, in which case, if XOR_CMP_OP is a zero constant, it will be overridden with *PEXP, @@ -7561,14 +7563,30 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, exp = res_ops[0]; } - /* Recognize and save a masking operation. */ + /* Recognize and save a masking operation. Combine it with an + incoming mask. */ if (pand_mask && gimple_binop_def_p (BIT_AND_EXPR, exp, res_ops) && uniform_integer_cst_p (res_ops[1])) { loc[1] = gimple_location (SSA_NAME_DEF_STMT (exp)); exp = res_ops[0]; and_mask = wi::to_wide (res_ops[1]); + unsigned prec_in = pand_mask->get_precision (); + if (prec_in) + { + unsigned prec_op = and_mask.get_precision (); + if (prec_in >= prec_op) + { + if (prec_in > prec_op) + and_mask = wide_int::from (and_mask, prec_in, UNSIGNED); + and_mask &= *pand_mask; + } + else + and_mask &= wide_int::from (*pand_mask, prec_op, UNSIGNED); + } } + else if (pand_mask) +and_mask = *pand_mask; /* Turn (a ^ b) [!]= 0 into a [!]= b. */ if (xor_p && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops) @@ -8019,6 +8037,8 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, return 0; } + /* Prepare to turn compares of signed quantities with zero into + sign-bit tests. */ bool lsignbit = false, rsignbit = false; if ((lcode == LT_EXPR || lcode == GE_EXPR) && integer_zerop (lr_arg) @@ -8028,6 +8048,31 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, lsignbit = true; lcode = (lcode == LT_EXPR ? NE_EXPR : EQ_EXPR); } + /* Turn compares of unsigned quantities with powers of two into + equality tests of masks. */ + else if ((lcode == LT_EXPR || lcode == GE_EXPR) + && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg)) + && TYPE_UNSIGNED (TREE_TYPE (ll_arg)) + && uniform_integer_cst_p (lr_arg) + && wi::popcount (wi::to_wide (lr_arg)) == 1) +{ + ll_and_mask = ~(wi::to_wide (lr_arg) - 1); + lcode = (lcode == GE_EXPR ? NE_EXPR : EQ_EXPR); + lr_arg = wide_int_to_tree (TREE_TYPE (ll_arg), ll_and_mask * 0); +} + /* Turn compares of unsigned quantities with powers of two minus one + into equality tests of masks. */ + el
[gcc(refs/users/aoliva/heads/testme)] ifcombine field merge: handle masks with sign extensions
https://gcc.gnu.org/g:5705e7db91851204f2fdbde7a2ee93e8c330f699 commit 5705e7db91851204f2fdbde7a2ee93e8c330f699 Author: Alexandre Oliva Date: Tue Dec 17 22:19:07 2024 -0300 ifcombine field merge: handle masks with sign extensions When a loaded field is sign extended, masked and compared, we used to drop from the mask the bits past the original field width, which is not correct. Take note of the fact that the mask covered copies of the sign bit, before clipping it, and arrange to test the sign bit if we're comparing with zero. Punt in other cases. for gcc/ChangeLog * gimple-fold.cc (decode_field_reference): Add psignbit parameter. Set it if the mask references sign-extending bits. (fold_truth_andor_for_ifcombine): Adjust calls with new variables. Swap them along with other r?_* variables. Handle extended sign bit compares with zero. for gcc/testsuite/ChangeLog * gcc.dg/field-merge-16.c: New. Diff: --- gcc/gimple-fold.cc| 69 ++- gcc/testsuite/gcc.dg/field-merge-16.c | 66 + 2 files changed, 125 insertions(+), 10 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 856ee5369a8c..b84269d6b417 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7514,6 +7514,9 @@ gimple_binop_def_p (enum tree_code code, tree t, tree op[2]) is initially set to a mask with nonzero precision, that mask is combined with the found mask, or adjusted in precision to match. + *PSIGNBIT is set to TRUE if, before clipping to *PBITSIZE, the mask + encompassed bits that corresponded to extensions of the sign bit. + *XOR_P is to be FALSE if EXP might be a XOR used in a compare, in which case, if XOR_CMP_OP is a zero constant, it will be overridden with *PEXP, *XOR_P will be set to TRUE, and the left-hand operand of the XOR will be @@ -7533,7 +7536,8 @@ static tree decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, HOST_WIDE_INT *pbitpos, bool *punsignedp, bool *preversep, bool *pvolatilep, - wide_int *pand_mask, bool *xor_p, tree *xor_cmp_op, + wide_int *pand_mask, bool *psignbit, + bool *xor_p, tree *xor_cmp_op, gimple **load, location_t loc[4]) { tree exp = *pexp; @@ -7545,6 +7549,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, machine_mode mode; *load = NULL; + *psignbit = false; /* All the optimizations using this function assume integer fields. There are problems with FP fields since the type_for_size call @@ -7708,12 +7713,23 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, if (outer_type && *pbitsize == TYPE_PRECISION (outer_type)) *punsignedp = TYPE_UNSIGNED (outer_type); - /* Make the mask the expected width. */ - if (and_mask.get_precision () != 0) -and_mask = wide_int::from (and_mask, *pbitsize, UNSIGNED); - if (pand_mask) -*pand_mask = and_mask; +{ + /* Make the mask the expected width. */ + if (and_mask.get_precision () != 0) + { + /* If the AND_MASK encompasses bits that would be extensions of +the sign bit, set *PSIGNBIT. */ + if (!unsignedp + && and_mask.get_precision () > *pbitsize + && (and_mask + & wi::mask (*pbitsize, true, and_mask.get_precision ())) != 0) + *psignbit = true; + and_mask = wide_int::from (and_mask, *pbitsize, UNSIGNED); + } + + *pand_mask = and_mask; +} return inner; } @@ -7995,6 +8011,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, HOST_WIDE_INT rnbitsize, rnbitpos, rnprec; bool ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp; bool ll_reversep, lr_reversep, rl_reversep, rr_reversep; + bool ll_signbit, lr_signbit, rl_signbit, rr_signbit; scalar_int_mode lnmode, lnmode2, rnmode; wide_int ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask; wide_int l_const, r_const; @@ -8114,19 +8131,19 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, bool l_xor = false, r_xor = false; ll_inner = decode_field_reference (&ll_arg, &ll_bitsize, &ll_bitpos, &ll_unsignedp, &ll_reversep, &volatilep, -&ll_and_mask, &l_xor, &lr_arg, +&ll_and_mask, &ll_signbit, &l_xor, &lr_arg, &ll_load, ll_loc); lr_inner = decode_field_reference (&lr_arg, &lr_bitsize, &lr_bitpos, &lr_unsignedp, &lr_reversep, &volatilep, -&lr_and_mask, &l_xor, 0, +&lr_and_m
[gcc/aoliva/heads/testme] ifcombine field merge: handle masks with sign extensions
The branch 'aoliva/heads/testme' was updated to point to: 5705e7db9185... ifcombine field merge: handle masks with sign extensions It previously pointed to: 2ed2573f6a31... ifcombine field merge: handle masks with sign extensions Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- 2ed2573... ifcombine field merge: handle masks with sign extensions Summary of changes (added commits): --- 5705e7d... ifcombine field merge: handle masks with sign extensions
[gcc r15-6315] c++: modules: Fix 32-bit overflow with 64-bit location_t [PR117970]
https://gcc.gnu.org/g:88aa69f8126db9a2d5f93b5c6c54cc01d21d1c6e commit r15-6315-g88aa69f8126db9a2d5f93b5c6c54cc01d21d1c6e Author: Lewis Hyatt Date: Tue Dec 17 21:26:18 2024 -0500 c++: modules: Fix 32-bit overflow with 64-bit location_t [PR117970] With the move to 64-bit location_t in r15-6016, I missed a spot in module.cc where a location_t was still being stored in a 32-bit int. Fixed. The xtreme-header* tests in modules.exp were still passing fine on lots of architectures that were tested (x86-64, i686, aarch64, sparc, riscv64), but the PR shows that they were failing in some particular risc-v multilib configurations. They pass now. gcc/cp/ChangeLog: PR c++/117970 * module.cc (module_state::read_ordinary_maps): Change argument to line_map_uint_t instead of unsigned int. Diff: --- gcc/cp/module.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index c3800b0f1256..f2a4fb16c078 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -3823,7 +3823,7 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state { void write_ordinary_maps (elf_out *to, range_t &, bool, unsigned *crc_ptr); - bool read_ordinary_maps (unsigned, unsigned); + bool read_ordinary_maps (line_map_uint_t, unsigned); void write_macro_maps (elf_out *to, range_t &, unsigned *crc_ptr); bool read_macro_maps (line_map_uint_t); @@ -17093,7 +17093,8 @@ module_state::write_macro_maps (elf_out *to, range_t &info, unsigned *crc_p) } bool -module_state::read_ordinary_maps (unsigned num_ord_locs, unsigned range_bits) +module_state::read_ordinary_maps (line_map_uint_t num_ord_locs, + unsigned range_bits) { bytes_in sec;
[gcc(refs/users/aoliva/heads/testme)] ifcombine field merge: handle masks with sign extensions
https://gcc.gnu.org/g:978d6fbaff29fc542eeaa2dfb37ed448780d3c12 commit 978d6fbaff29fc542eeaa2dfb37ed448780d3c12 Author: Alexandre Oliva Date: Tue Dec 17 22:19:07 2024 -0300 ifcombine field merge: handle masks with sign extensions When a loaded field is sign extended, masked and compared, we used to drop from the mask the bits past the original field width, which is not correct. Take note of the fact that the mask covered copies of the sign bit, before clipping it, and arrange to test the sign bit if we're comparing with zero. Punt in other cases. for gcc/ChangeLog * gimple-fold.cc (decode_field_reference): Add psignbit parameter. Set it if the mask references sign-extending bits. (fold_truth_andor_for_ifcombine): Adjust calls with new variables. Swap them along with other r?_* variables. Handle extended sign bit compares with zero. for gcc/testsuite/ChangeLog * gcc.dg/field-merge-16.c: New. Diff: --- gcc/gimple-fold.cc| 69 ++- gcc/testsuite/gcc.dg/field-merge-16.c | 66 + 2 files changed, 125 insertions(+), 10 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 856ee5369a8c..6986d469edef 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7514,6 +7514,9 @@ gimple_binop_def_p (enum tree_code code, tree t, tree op[2]) is initially set to a mask with nonzero precision, that mask is combined with the found mask, or adjusted in precision to match. + *PSIGNBIT is set to TRUE if, before clipping to *PBITSIZE, the mask + encompassed bits that corresponded to extensions of the sign bit. + *XOR_P is to be FALSE if EXP might be a XOR used in a compare, in which case, if XOR_CMP_OP is a zero constant, it will be overridden with *PEXP, *XOR_P will be set to TRUE, and the left-hand operand of the XOR will be @@ -7533,7 +7536,8 @@ static tree decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, HOST_WIDE_INT *pbitpos, bool *punsignedp, bool *preversep, bool *pvolatilep, - wide_int *pand_mask, bool *xor_p, tree *xor_cmp_op, + wide_int *pand_mask, bool *psignbit, + bool *xor_p, tree *xor_cmp_op, gimple **load, location_t loc[4]) { tree exp = *pexp; @@ -7545,6 +7549,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, machine_mode mode; *load = NULL; + *psignbit = false; /* All the optimizations using this function assume integer fields. There are problems with FP fields since the type_for_size call @@ -7708,12 +7713,23 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, if (outer_type && *pbitsize == TYPE_PRECISION (outer_type)) *punsignedp = TYPE_UNSIGNED (outer_type); - /* Make the mask the expected width. */ - if (and_mask.get_precision () != 0) -and_mask = wide_int::from (and_mask, *pbitsize, UNSIGNED); - if (pand_mask) -*pand_mask = and_mask; +{ + /* Make the mask the expected width. */ + if (and_mask.get_precision () != 0) + { + /* If the AND_MASK encompasses bits that would be extensions of +the sign bit, set *PSIGNBIT. */ + if (!unsignedp + && and_mask.get_precision () > *pbitsize + && (and_mask + & wi::mask (*pbitsize, true, and_mask.get_precision ( + *psignbit = true; + and_mask = wide_int::from (and_mask, *pbitsize, UNSIGNED); + } + + *pand_mask = and_mask; +} return inner; } @@ -7995,6 +8011,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, HOST_WIDE_INT rnbitsize, rnbitpos, rnprec; bool ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp; bool ll_reversep, lr_reversep, rl_reversep, rr_reversep; + bool ll_signbit, lr_signbit, rl_signbit, rr_signbit; scalar_int_mode lnmode, lnmode2, rnmode; wide_int ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask; wide_int l_const, r_const; @@ -8114,19 +8131,19 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, bool l_xor = false, r_xor = false; ll_inner = decode_field_reference (&ll_arg, &ll_bitsize, &ll_bitpos, &ll_unsignedp, &ll_reversep, &volatilep, -&ll_and_mask, &l_xor, &lr_arg, +&ll_and_mask, &ll_signbit, &l_xor, &lr_arg, &ll_load, ll_loc); lr_inner = decode_field_reference (&lr_arg, &lr_bitsize, &lr_bitpos, &lr_unsignedp, &lr_reversep, &volatilep, -&lr_and_mask, &l_xor, 0, +&lr_and_mask,
[gcc(refs/users/aoliva/heads/testme)] ifcombine field merge: handle bitfield zero tests in range tests
https://gcc.gnu.org/g:9675c1d50dd009097ac07c5fc505e1104995d75c commit 9675c1d50dd009097ac07c5fc505e1104995d75c Author: Alexandre Oliva Date: Tue Dec 17 22:18:43 2024 -0300 ifcombine field merge: handle bitfield zero tests in range tests Some bitfield compares with zero are optimized to range tests, so instead of X & ~(Bit - 1) != 0 what reaches ifcombine is X > (Bit - 1), where Bit is a power of two and X is unsigned. This patch recognizes this optimized form of masked compares, and attempts to merge them like masked compares, which enables some more field merging that a folder version of fold_truth_andor used to handle without additional effort. I haven't seen X & ~(Bit - 1) == 0 become X <= (Bit - 1), or X < Bit for that matter, but it was easy enough to handle the former symmetrically to the above. The latter was also easy enough, and so was its symmetric, X >= Bit, that is handled like X & ~(Bit - 1) != 0. for gcc/ChangeLog * gimple-fold.cc (decode_field_reference): Accept incoming mask. (fold_truth_andor_for_ifcombine): Handle some compares with powers of two, minus 1 or 0, like masked compares with zero. for gcc/testsuite/ChangeLog * gcc.dg/field-merge-15.c: New. Diff: --- gcc/gimple-fold.cc| 71 +-- gcc/testsuite/gcc.dg/field-merge-15.c | 36 ++ 2 files changed, 104 insertions(+), 3 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 06913d57f8ae..856ee5369a8c 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7509,8 +7509,10 @@ gimple_binop_def_p (enum tree_code code, tree t, tree op[2]) *PREVERSEP is set to the storage order of the field. - *PAND_MASK is set to the mask found in a BIT_AND_EXPR, if any. - If PAND_MASK *is NULL, BIT_AND_EXPR is not recognized. + *PAND_MASK is set to the mask found in a BIT_AND_EXPR, if any. If + PAND_MASK *is NULL, BIT_AND_EXPR is not recognized. If *PAND_MASK + is initially set to a mask with nonzero precision, that mask is + combined with the found mask, or adjusted in precision to match. *XOR_P is to be FALSE if EXP might be a XOR used in a compare, in which case, if XOR_CMP_OP is a zero constant, it will be overridden with *PEXP, @@ -7561,14 +7563,30 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, exp = res_ops[0]; } - /* Recognize and save a masking operation. */ + /* Recognize and save a masking operation. Combine it with an + incoming mask. */ if (pand_mask && gimple_binop_def_p (BIT_AND_EXPR, exp, res_ops) && uniform_integer_cst_p (res_ops[1])) { loc[1] = gimple_location (SSA_NAME_DEF_STMT (exp)); exp = res_ops[0]; and_mask = wi::to_wide (res_ops[1]); + unsigned prec_in = pand_mask->get_precision (); + if (prec_in) + { + unsigned prec_op = and_mask.get_precision (); + if (prec_in >= prec_op) + { + if (prec_in > prec_op) + and_mask = wide_int::from (and_mask, prec_in, UNSIGNED); + and_mask &= *pand_mask; + } + else + and_mask &= wide_int::from (*pand_mask, prec_op, UNSIGNED); + } } + else if (pand_mask) +and_mask = *pand_mask; /* Turn (a ^ b) [!]= 0 into a [!]= b. */ if (xor_p && gimple_binop_def_p (BIT_XOR_EXPR, exp, res_ops) @@ -8019,6 +8037,8 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, return 0; } + /* Prepare to turn compares of signed quantities with zero into + sign-bit tests. */ bool lsignbit = false, rsignbit = false; if ((lcode == LT_EXPR || lcode == GE_EXPR) && integer_zerop (lr_arg) @@ -8028,6 +8048,31 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, lsignbit = true; lcode = (lcode == LT_EXPR ? NE_EXPR : EQ_EXPR); } + /* Turn compares of unsigned quantities with powers of two into + equality tests of masks. */ + else if ((lcode == LT_EXPR || lcode == GE_EXPR) + && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg)) + && TYPE_UNSIGNED (TREE_TYPE (ll_arg)) + && uniform_integer_cst_p (lr_arg) + && wi::popcount (wi::to_wide (lr_arg)) == 1) +{ + ll_and_mask = ~(wi::to_wide (lr_arg) - 1); + lcode = (lcode == GE_EXPR ? NE_EXPR : EQ_EXPR); + lr_arg = wide_int_to_tree (TREE_TYPE (ll_arg), ll_and_mask * 0); +} + /* Turn compares of unsigned quantities with powers of two minus one + into equality tests of masks. */ + else if ((lcode == LE_EXPR || lcode == GT_EXPR) + && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg)) + && TYPE_UNSIGNED (TREE_TYPE (ll_arg)) + && uniform_integer_cst_p (lr_arg) + && wi::popcount (wi::to_wide (lr_arg) + 1) == 1) +{ + ll_and_mask =
[gcc/aoliva/heads/testme] (2 commits) ifcombine field merge: handle masks with sign extensions
The branch 'aoliva/heads/testme' was updated to point to: 978d6fbaff29... ifcombine field merge: handle masks with sign extensions It previously pointed to: 85677ef350e4... ifcombine field merge: handle bitfield zero tests in range Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- 85677ef... ifcombine field merge: handle bitfield zero tests in range Summary of changes (added commits): --- 978d6fb... ifcombine field merge: handle masks with sign extensions 9675c1d... ifcombine field merge: handle bitfield zero tests in range
[gcc(refs/users/aoliva/heads/testme)] ifcombine field merge: handle masks with sign extensions
https://gcc.gnu.org/g:2ed2573f6a310523080c45d5c0e8e14e8303285a commit 2ed2573f6a310523080c45d5c0e8e14e8303285a Author: Alexandre Oliva Date: Tue Dec 17 22:19:07 2024 -0300 ifcombine field merge: handle masks with sign extensions When a loaded field is sign extended, masked and compared, we used to drop from the mask the bits past the original field width, which is not correct. Take note of the fact that the mask covered copies of the sign bit, before clipping it, and arrange to test the sign bit if we're comparing with zero. Punt in other cases. for gcc/ChangeLog * gimple-fold.cc (decode_field_reference): Add psignbit parameter. Set it if the mask references sign-extending bits. (fold_truth_andor_for_ifcombine): Adjust calls with new variables. Swap them along with other r?_* variables. Handle extended sign bit compares with zero. for gcc/testsuite/ChangeLog * gcc.dg/field-merge-16.c: New. Diff: --- gcc/gimple-fold.cc| 69 ++- gcc/testsuite/gcc.dg/field-merge-16.c | 66 + 2 files changed, 125 insertions(+), 10 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 856ee5369a8c..6986d469edef 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7514,6 +7514,9 @@ gimple_binop_def_p (enum tree_code code, tree t, tree op[2]) is initially set to a mask with nonzero precision, that mask is combined with the found mask, or adjusted in precision to match. + *PSIGNBIT is set to TRUE if, before clipping to *PBITSIZE, the mask + encompassed bits that corresponded to extensions of the sign bit. + *XOR_P is to be FALSE if EXP might be a XOR used in a compare, in which case, if XOR_CMP_OP is a zero constant, it will be overridden with *PEXP, *XOR_P will be set to TRUE, and the left-hand operand of the XOR will be @@ -7533,7 +7536,8 @@ static tree decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, HOST_WIDE_INT *pbitpos, bool *punsignedp, bool *preversep, bool *pvolatilep, - wide_int *pand_mask, bool *xor_p, tree *xor_cmp_op, + wide_int *pand_mask, bool *psignbit, + bool *xor_p, tree *xor_cmp_op, gimple **load, location_t loc[4]) { tree exp = *pexp; @@ -7545,6 +7549,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, machine_mode mode; *load = NULL; + *psignbit = false; /* All the optimizations using this function assume integer fields. There are problems with FP fields since the type_for_size call @@ -7708,12 +7713,23 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, if (outer_type && *pbitsize == TYPE_PRECISION (outer_type)) *punsignedp = TYPE_UNSIGNED (outer_type); - /* Make the mask the expected width. */ - if (and_mask.get_precision () != 0) -and_mask = wide_int::from (and_mask, *pbitsize, UNSIGNED); - if (pand_mask) -*pand_mask = and_mask; +{ + /* Make the mask the expected width. */ + if (and_mask.get_precision () != 0) + { + /* If the AND_MASK encompasses bits that would be extensions of +the sign bit, set *PSIGNBIT. */ + if (!unsignedp + && and_mask.get_precision () > *pbitsize + && (and_mask + & wi::mask (*pbitsize, true, and_mask.get_precision ( + *psignbit = true; + and_mask = wide_int::from (and_mask, *pbitsize, UNSIGNED); + } + + *pand_mask = and_mask; +} return inner; } @@ -7995,6 +8011,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, HOST_WIDE_INT rnbitsize, rnbitpos, rnprec; bool ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp; bool ll_reversep, lr_reversep, rl_reversep, rr_reversep; + bool ll_signbit, lr_signbit, rl_signbit, rr_signbit; scalar_int_mode lnmode, lnmode2, rnmode; wide_int ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask; wide_int l_const, r_const; @@ -8114,19 +8131,19 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, bool l_xor = false, r_xor = false; ll_inner = decode_field_reference (&ll_arg, &ll_bitsize, &ll_bitpos, &ll_unsignedp, &ll_reversep, &volatilep, -&ll_and_mask, &l_xor, &lr_arg, +&ll_and_mask, &ll_signbit, &l_xor, &lr_arg, &ll_load, ll_loc); lr_inner = decode_field_reference (&lr_arg, &lr_bitsize, &lr_bitpos, &lr_unsignedp, &lr_reversep, &volatilep, -&lr_and_mask, &l_xor, 0, +&lr_and_mask,
[gcc/aoliva/heads/testme] ifcombine field merge: handle masks with sign extensions
The branch 'aoliva/heads/testme' was updated to point to: 2ed2573f6a31... ifcombine field merge: handle masks with sign extensions It previously pointed to: 978d6fbaff29... ifcombine field merge: handle masks with sign extensions Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- 978d6fb... ifcombine field merge: handle masks with sign extensions Summary of changes (added commits): --- 2ed2573... ifcombine field merge: handle masks with sign extensions
[gcc/aoliva/heads/testme] ifcombine field merge: handle masks with sign extensions
The branch 'aoliva/heads/testme' was updated to point to: ae42ade2c98f... ifcombine field merge: handle masks with sign extensions It previously pointed to: 5705e7db9185... ifcombine field merge: handle masks with sign extensions Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- 5705e7d... ifcombine field merge: handle masks with sign extensions Summary of changes (added commits): --- ae42ade... ifcombine field merge: handle masks with sign extensions
[gcc r15-6316] Documentation: Fix paste-o in recent OpenMP/OpenACC patch
https://gcc.gnu.org/g:b34fbab529e64dbeb6db70263e35373c200f899a commit r15-6316-gb34fbab529e64dbeb6db70263e35373c200f899a Author: Sandra Loosemore Date: Wed Dec 18 03:51:54 2024 + Documentation: Fix paste-o in recent OpenMP/OpenACC patch gcc/ChangeLog * doc/extend.texi (OpenACC): Fix paste-o. Diff: --- gcc/doc/extend.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 54465ddc23a1..f045159963ed 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -29403,7 +29403,7 @@ GCC strives to be compatible with the @uref{https://www.openacc.org/, OpenACC Application Programming Interface v2.6}. -To enable the processing of OpenACC directives @samp{#pragma omp} +To enable the processing of OpenACC directives @samp{#pragma acc} in C and C++, GCC needs to be invoked with the @option{-fopenacc} option. This option also arranges for automatic linking of the OpenACC runtime library.
[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Appel méthode shift descriptor dans gfc_trans_pointer_assignment
https://gcc.gnu.org/g:60a05098803896411deaaccadc883e2223b8f99d commit 60a05098803896411deaaccadc883e2223b8f99d Author: Mikael Morin Date: Tue Dec 17 22:37:18 2024 +0100 Appel méthode shift descriptor dans gfc_trans_pointer_assignment Diff: --- gcc/fortran/trans-array.cc | 129 +++-- gcc/fortran/trans-array.h | 1 + gcc/fortran/trans-expr.cc | 28 +- 3 files changed, 129 insertions(+), 29 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index fdd990592092..f25318bc3e2b 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -1151,13 +1151,136 @@ gfc_conv_shift_descriptor_lbound (stmtblock_t* block, tree desc, } +class lb_info +{ +public: + virtual gfc_expr *lower_bound (int dim) const = 0; +}; + + +class unset_lb : public lb_info +{ +public: + virtual gfc_expr *lower_bound (int) const { return nullptr; } +}; + + +class defined_lb : public lb_info +{ + int rank; + gfc_expr * const * lower_bounds; + +public: + defined_lb (int arg_rank, gfc_expr * const arg_lower_bounds[GFC_MAX_DIMENSIONS]) +: rank(arg_rank), lower_bounds(arg_lower_bounds) { } + virtual gfc_expr *lower_bound (int dim) const { return lower_bounds[dim]; } +}; + + static void -conv_shift_descriptor (stmtblock_t* block, tree desc, int rank) +conv_shift_descriptor (stmtblock_t *block, tree desc, int rank, + const lb_info &info) { /* Apply a shift of the lbound when supplied. */ for (int dim = 0; dim < rank; ++dim) -gfc_conv_shift_descriptor_lbound (block, desc, dim, - gfc_index_one_node); +{ + gfc_expr *lb_expr = info.lower_bound(dim); + + tree lower_bound; + if (lb_expr == nullptr) + lower_bound = gfc_index_one_node; + else + { + gfc_se lb_se; + + gfc_init_se (&lb_se, nullptr); + gfc_conv_expr (&lb_se, lb_expr); + + gfc_add_block_to_block (block, &lb_se.pre); + tree lb_var = gfc_create_var (TREE_TYPE (lb_se.expr), "lower_bound"); + gfc_add_modify (block, lb_var, lb_se.expr); + gfc_add_block_to_block (block, &lb_se.post); + + lower_bound = lb_var; + } + + gfc_conv_shift_descriptor_lbound (block, desc, dim, lower_bound); +} +} + + +static void +conv_shift_descriptor (stmtblock_t* block, tree desc, int rank) +{ + conv_shift_descriptor (block, desc, rank, unset_lb ()); +} + + +static void +conv_shift_descriptor (stmtblock_t *block, tree desc, int rank, + gfc_expr * const lower_bounds[GFC_MAX_DIMENSIONS]) +{ + conv_shift_descriptor (block, desc, rank, defined_lb (rank, lower_bounds)); +} + + +static void +conv_shift_descriptor (stmtblock_t *block, tree desc, + const gfc_array_spec &as) +{ + conv_shift_descriptor (block, desc, as.rank, as.lower); +} + + +static void +set_type (array_type &type, array_type value) +{ + gcc_assert (type == AS_UNKNOWN || type == value); + type = value; +} + + +static void +array_ref_to_array_spec (const gfc_array_ref &ref, gfc_array_spec &spec) +{ + spec.rank = ref.dimen; + spec.corank = ref.codimen; + + spec.type = AS_UNKNOWN; + spec.cotype = AS_ASSUMED_SIZE; + + for (int dim = 0; dim < spec.rank + spec.corank; dim++) +switch (ref.dimen_type[dim]) + { + case DIMEN_ELEMENT: + spec.upper[dim] = ref.start[dim]; + set_type (spec.type, AS_EXPLICIT); + break; + + case DIMEN_RANGE: + spec.lower[dim] = ref.start[dim]; + spec.upper[dim] = ref.end[dim]; + if (spec.upper[dim] == nullptr) + set_type (spec.type, AS_DEFERRED); + else + set_type (spec.type, AS_EXPLICIT); + break; + + default: + break; + } +} + + +void +gfc_conv_shift_descriptor (stmtblock_t *block, tree desc, + const gfc_array_ref &ar) +{ + gfc_array_spec as; + + array_ref_to_array_spec (ar, as); + + conv_shift_descriptor (block, desc, as); } diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h index 9fea0604c423..a7f29f7b84f9 100644 --- a/gcc/fortran/trans-array.h +++ b/gcc/fortran/trans-array.h @@ -214,6 +214,7 @@ tree gfc_get_cfi_dim_sm (tree, tree); /* Shift lower bound of descriptor, updating ubound and offset. */ void gfc_conv_shift_descriptor_lbound (stmtblock_t*, tree, int, tree); +void gfc_conv_shift_descriptor (stmtblock_t*, tree, const gfc_array_ref &); /* Add pre-loop scalarization code for intrinsic functions which require special handling. */ diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 303c0a254308..efe1e59f560e 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -11078,32 +11078,8 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2) } } else - { - /* Bounds remapping. Just shift the lower bounds. */ - -
[gcc r15-6313] c++: print NONTYPE_ARGUMENT_PACK [PR118073]
https://gcc.gnu.org/g:91733c095ee714c0b384153754c6327d5506cd19 commit r15-6313-g91733c095ee714c0b384153754c6327d5506cd19 Author: Marek Polacek Date: Tue Dec 17 13:44:22 2024 -0500 c++: print NONTYPE_ARGUMENT_PACK [PR118073] This PR points out that we're not pretty-printing NONTYPE_ARGUMENT_PACK so the compiler emits the ugly: 'nontype_argument_pack' not supported by dump_expr> Fixed thus. I've wrapped the elements of the pack in { } because that's what cxx_pretty_printer::expression does. PR c++/118073 gcc/cp/ChangeLog: * error.cc (dump_expr) : New case. gcc/testsuite/ChangeLog: * g++.dg/diagnostic/arg-pack1.C: New test. Diff: --- gcc/cp/error.cc | 15 +++ gcc/testsuite/g++.dg/diagnostic/arg-pack1.C | 10 ++ 2 files changed, 25 insertions(+) diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc index 4736f4875eaf..8c0644fba7ea 100644 --- a/gcc/cp/error.cc +++ b/gcc/cp/error.cc @@ -3173,6 +3173,21 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags) dump_expr_list (pp, t, flags); break; +case NONTYPE_ARGUMENT_PACK: + { + tree args = ARGUMENT_PACK_ARGS (t); + int len = TREE_VEC_LENGTH (args); + pp_cxx_left_brace (pp); + for (int i = 0; i < len; ++i) + { + if (i > 0) + pp_separate_with_comma (pp); + dump_expr (pp, TREE_VEC_ELT (args, i), flags); + } + pp_cxx_right_brace (pp); + break; + } + /* This list is incomplete, but should suffice for now. It is very important that `sorry' does not call `report_error_function'. That could cause an infinite loop. */ diff --git a/gcc/testsuite/g++.dg/diagnostic/arg-pack1.C b/gcc/testsuite/g++.dg/diagnostic/arg-pack1.C new file mode 100644 index ..643fc7f665e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/arg-pack1.C @@ -0,0 +1,10 @@ +// PR c++/118073 +// { dg-do compile { target c++11 } } + +template +struct index_sequence {}; + +void foo() +{ +index_sequence<5> bar = index_sequence<1>(); // { dg-error {conversion from 'index_sequence<\{1\}>' to non-scalar type 'index_sequence<\{5\}>' requested} } +}
[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Utilisation gfc_clear_descriptor dans gfc_conv_derived_to_class
https://gcc.gnu.org/g:c689371eb754d4b4cdfb40c25b5897a927fadfec commit c689371eb754d4b4cdfb40c25b5897a927fadfec Author: Mikael Morin Date: Wed Dec 11 16:03:10 2024 +0100 Utilisation gfc_clear_descriptor dans gfc_conv_derived_to_class essai suppression Suppression fonction inutilisée Sauvegarde compilation OK Correction régression Sauvegarde correction null_actual_6 Commentage fonction inutilisée Correction bornes descripteur null Diff: --- gcc/fortran/trans-array.cc | 339 +++-- gcc/fortran/trans-array.h | 4 +- gcc/fortran/trans-expr.cc | 87 ++-- 3 files changed, 373 insertions(+), 57 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 4a686e8bf20b..d7e1366ba26a 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -592,10 +592,10 @@ get_size_info (gfc_typespec &ts) if (POINTER_TYPE_P (type)) type = TREE_TYPE (type); gcc_assert (TREE_CODE (type) == ARRAY_TYPE); - tree elt_type = TREE_TYPE (type); + tree char_type = TREE_TYPE (type); tree len = ts.u.cl->backend_decl; return fold_build2_loc (input_location, MULT_EXPR, size_type_node, - size_in_bytes (elt_type), + size_in_bytes (char_type), fold_convert (size_type_node, len)); } @@ -613,8 +613,61 @@ get_size_info (gfc_typespec &ts) } +class init_info +{ +public: + virtual bool initialize_data () const { return false; } + virtual tree get_data_value () const { return NULL_TREE; } + virtual gfc_typespec *get_type () const { return nullptr; } +}; + + +class default_init : public init_info +{ +private: + const symbol_attribute &attr; + +public: + default_init (const symbol_attribute &arg_attr) : attr(arg_attr) { } + virtual bool initialize_data () const { return !attr.pointer; } + virtual tree get_data_value () const { +if (!initialize_data ()) + return NULL_TREE; + +return null_pointer_node; + } +}; + +class nullification : public init_info +{ +private: + gfc_typespec &ts; + +public: + nullification(gfc_typespec &arg_ts) : ts(arg_ts) { } + virtual bool initialize_data () const { return true; } + virtual tree get_data_value () const { return null_pointer_node; } + virtual gfc_typespec *get_type () const { return &ts; } +}; + +class scalar_value : public init_info +{ +private: + gfc_typespec &ts; + tree value; + +public: + scalar_value(gfc_typespec &arg_ts, tree arg_value) +: ts(arg_ts), value(arg_value) { } + virtual bool initialize_data () const { return true; } + virtual tree get_data_value () const { return value; } + virtual gfc_typespec *get_type () const { return &ts; } +}; + + static tree -build_dtype (gfc_typespec &ts, int rank, const symbol_attribute &) +build_dtype (gfc_typespec &ts, int rank, const symbol_attribute &, +const init_info &init) { vec *v = nullptr; @@ -622,11 +675,17 @@ build_dtype (gfc_typespec &ts, int rank, const symbol_attribute &) tree fields = TYPE_FIELDS (type); - if (ts.type != BT_CLASS) + gfc_typespec *type_info = init.get_type (); + if (type_info == nullptr) +type_info = &ts; + + if (!(type_info->type == BT_CLASS + || (type_info->type == BT_CHARACTER + && type_info->deferred))) { tree elem_len_field = gfc_advance_chain (fields, GFC_DTYPE_ELEM_LEN); tree elem_len_val = fold_convert (TREE_TYPE (elem_len_field), - get_size_info (ts)); + get_size_info (*type_info)); CONSTRUCTOR_APPEND_ELT (v, elem_len_field, elem_len_val); } @@ -641,11 +700,11 @@ build_dtype (gfc_typespec &ts, int rank, const symbol_attribute &) CONSTRUCTOR_APPEND_ELT (v, rank_field, rank_val); } - if (ts.type != BT_CLASS) + if (type_info->type != BT_CLASS) { tree type_info_field = gfc_advance_chain (fields, GFC_DTYPE_TYPE); tree type_info_val = build_int_cst (TREE_TYPE (type_info_field), - get_type_info (ts)); + get_type_info (*type_info)); CONSTRUCTOR_APPEND_ELT (v, type_info_field, type_info_val); } @@ -656,8 +715,8 @@ build_dtype (gfc_typespec &ts, int rank, const symbol_attribute &) /* Build a null array descriptor constructor. */ vec * -get_default_descriptor_init (tree type, gfc_typespec &ts, int rank, -const symbol_attribute &attr) +get_descriptor_init (tree type, gfc_typespec &ts, int rank, +const symbol_attribute &attr, const init_info &init) { vec *v = nullptr; @@ -666,15 +725,15 @@ get_default_descriptor_init (tree type, gfc_typespec &ts, int rank, tree fields = TYPE_FIELDS (type); /* Don't init pointers by default. */ - if
[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Déplacement shift descriptor vers gfc_conv_array_parameter
https://gcc.gnu.org/g:efc0e0bed4f67e00fb93c3a7f8e82a804ae1450f commit efc0e0bed4f67e00fb93c3a7f8e82a804ae1450f Author: Mikael Morin Date: Tue Dec 17 17:27:24 2024 +0100 Déplacement shift descriptor vers gfc_conv_array_parameter Diff: --- gcc/fortran/trans-array.cc | 49 ++ gcc/fortran/trans-array.h | 2 +- gcc/fortran/trans-expr.cc | 18 + 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index d7e1366ba26a..fdd990592092 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -1151,6 +1151,43 @@ gfc_conv_shift_descriptor_lbound (stmtblock_t* block, tree desc, } +static void +conv_shift_descriptor (stmtblock_t* block, tree desc, int rank) +{ + /* Apply a shift of the lbound when supplied. */ + for (int dim = 0; dim < rank; ++dim) +gfc_conv_shift_descriptor_lbound (block, desc, dim, + gfc_index_one_node); +} + + +static bool +keep_descriptor_lower_bound (gfc_expr *e) +{ + gfc_ref *ref; + + /* Detect any array references with vector subscripts. */ + for (ref = e->ref; ref; ref = ref->next) +if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT + && ref->u.ar.type != AR_FULL) + { + int dim; + for (dim = 0; dim < ref->u.ar.dimen; dim++) + if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR) + break; + if (dim < ref->u.ar.dimen) + break; + } + + /* Array references with vector subscripts and non-variable + expressions need be converted to a one-based descriptor. */ + if (ref || e->expr_type != EXPR_VARIABLE) +return false; + + return true; +} + + /* Obtain offsets for trans-types.cc(gfc_get_array_descr_info). */ void @@ -9350,7 +9387,7 @@ is_pointer (gfc_expr *e) void gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, bool g77, const gfc_symbol *fsym, const char *proc_name, - tree *size, tree *lbshift, tree *packed) + tree *size, bool maybe_shift, tree *packed) { tree ptr; tree desc; @@ -9585,13 +9622,9 @@ gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, bool g77, stmtblock_t block; gfc_init_block (&block); - if (lbshift && *lbshift) - { - /* Apply a shift of the lbound when supplied. */ - for (int dim = 0; dim < expr->rank; ++dim) - gfc_conv_shift_descriptor_lbound (&block, se->expr, dim, - *lbshift); - } + if (maybe_shift && !keep_descriptor_lower_bound (expr)) + conv_shift_descriptor (&block, se->expr, expr->rank); + tmp = gfc_class_data_get (ctree); if (expr->rank > 1 && CLASS_DATA (fsym)->as->rank != expr->rank && CLASS_DATA (fsym)->as->type == AS_EXPLICIT && !no_pack) diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h index 4b3c4c644924..9fea0604c423 100644 --- a/gcc/fortran/trans-array.h +++ b/gcc/fortran/trans-array.h @@ -158,7 +158,7 @@ tree gfc_get_array_span (tree, gfc_expr *); void gfc_conv_expr_descriptor (gfc_se *, gfc_expr *); /* Convert an array for passing as an actual function parameter. */ void gfc_conv_array_parameter (gfc_se *, gfc_expr *, bool, const gfc_symbol *, - const char *, tree *, tree * = nullptr, + const char *, tree *, bool = false, tree * = nullptr); /* These work with both descriptors and descriptorless arrays. */ diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index a6480077a3bc..6708b78c0fe8 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -996,25 +996,9 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym, && (ref || e->rank != fsym->ts.u.derived->components->as->rank)) fsym->attr.contiguous = 1; - /* Detect any array references with vector subscripts. */ - for (ref = e->ref; ref; ref = ref->next) - if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT - && ref->u.ar.type != AR_FULL) - { - for (dim = 0; dim < ref->u.ar.dimen; dim++) - if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR) - break; - if (dim < ref->u.ar.dimen) - break; - } - /* Array references with vector subscripts and non-variable -expressions need be converted to a one-based descriptor. */ - if (ref || e->expr_type != EXPR_VARIABLE) - lbshift = gfc_index_one_node; - parmse->expr = var; gfc_conv_array_parameter (parmse, e, false, fsym, proc_name, nullptr, - &lbshift, &packed); +
[gcc] Created branch 'mikael/heads/refactor_descriptor_v01' in namespace 'refs/users'
The branch 'mikael/heads/refactor_descriptor_v01' was created in namespace 'refs/users' pointing to: efc0e0bed4f6... Déplacement shift descriptor vers gfc_conv_array_parameter
[gcc r15-6308] c++: ICE initializing array of aggrs [PR117985]
https://gcc.gnu.org/g:40e5636e086e51f5908a1a01be9cba2218dc26d8 commit r15-6308-g40e5636e086e51f5908a1a01be9cba2218dc26d8 Author: Marek Polacek Date: Thu Dec 12 14:56:07 2024 -0500 c++: ICE initializing array of aggrs [PR117985] This crash started with my r12-7803 but I believe the problem lies elsewhere. build_vec_init has cleanup_flags whose purpose is -- if I grok this correctly -- to avoid destructing an object multiple times. Let's say we are initializing an array of A. Then we might end up in a scenario similar to initlist-eh1.C: try { call A::A in a loop // #0 try { call a fn using the array } finally { // #1 call A::~A in a loop } } catch { // #2 call A::~A in a loop } cleanup_flags makes us emit a statement like D.3048 = 2; at #0 to disable performing the cleanup at #2, since #1 will take care of the destruction of the array. But if we are not emitting the loop because we can use a constant initializer (and use a single { a, b, ...}), we shouldn't generate the statement resetting the iterator to its initial value. Otherwise we crash in gimplify_var_or_parm_decl because it gets the stray decl D.3048. PR c++/117985 gcc/cp/ChangeLog: * init.cc (build_vec_init): Pop CLEANUP_FLAGS if we're not generating the loop. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-array23.C: New test. * g++.dg/cpp0x/initlist-array24.C: New test. Diff: --- gcc/cp/init.cc| 9 + gcc/testsuite/g++.dg/cpp0x/initlist-array23.C | 28 +++ gcc/testsuite/g++.dg/cpp0x/initlist-array24.C | 27 ++ 3 files changed, 64 insertions(+) diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index ae516407c927..7dcc1152c720 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -5109,6 +5109,15 @@ build_vec_init (tree base, tree maxindex, tree init, { if (!saw_non_const) { + /* If we're not generating the loop, we don't need to reset the +iterator. */ + if (cleanup_flags + && !vec_safe_is_empty (*cleanup_flags)) + { + auto l = (*cleanup_flags)->last (); + gcc_assert (TREE_PURPOSE (l) == iterator); + (*cleanup_flags)->pop (); + } tree const_init = build_constructor (atype, const_vec); return build2 (INIT_EXPR, atype, obase, const_init); } diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array23.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array23.C new file mode 100644 index ..cda2afb9fccc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array23.C @@ -0,0 +1,28 @@ +// PR c++/117985 +// { dg-do compile { target c++11 } } + +struct _Vector_impl { + constexpr +_Vector_impl() {} +}; +struct _Vector_base { + ~_Vector_base(); + _Vector_impl _M_impl; +}; +struct vector : private _Vector_base {}; +struct string { + string(); +}; +struct VEC { + vector pane{}; +}; +struct FOO { + VEC screen[1]{}; + string debug_name; +}; + +int +main () +{ + FOO{}; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array24.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array24.C new file mode 100644 index ..7dda00d5c0b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array24.C @@ -0,0 +1,27 @@ +// PR c++/117985 +// { dg-do compile { target c++20 } } + +struct _Vector_impl { + constexpr _Vector_impl() {} +}; +struct _Vector_base { + constexpr ~_Vector_base() {} + _Vector_impl _M_impl; +}; +struct vector : private _Vector_base {}; +struct string { + string(); +}; +struct VEC { + vector pane{}; +}; +struct FOO { + VEC screen[1]{}; + string debug_name; +}; + +int +main () +{ + FOO{}; +}
[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Suppression variables inutilisées
https://gcc.gnu.org/g:4aa6cc9282639d1e71a2eeed28f7dc91bc5d5e3a commit 4aa6cc9282639d1e71a2eeed28f7dc91bc5d5e3a Author: Mikael Morin Date: Tue Dec 17 18:55:23 2024 +0100 Suppression variables inutilisées Diff: --- gcc/fortran/trans-expr.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 6708b78c0fe8..303c0a254308 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -982,8 +982,6 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym, stmtblock_t block; gfc_init_block (&block); gfc_ref *ref; - int dim; - tree lbshift = NULL_TREE; /* Array refs with sections indicate, that a for a formal argument expecting contiguous repacking needs to be done. */
[gcc r15-6310] Documentation: Make OpenMP/OpenACC docs easier to find [PR26154]
https://gcc.gnu.org/g:ef458b3fa75537cb2d16f4ce61bc52642ddefd8a commit r15-6310-gef458b3fa75537cb2d16f4ce61bc52642ddefd8a Author: Sandra Loosemore Date: Tue Dec 17 15:19:36 2024 + Documentation: Make OpenMP/OpenACC docs easier to find [PR26154] PR c/26154 is one of our oldest documentation issues. The only discussion of OpenMP support in the GCC manual is buried in the "C Dialect Options" section, with nothing at all under "Extensions". The Fortran manual does have separate sections for OpenMP and OpenACC extensions so I have copy-edited/adapted that text for similar sections in the GCC manual, as well as breaking out the OpenMP and OpenACC options into their own section (they apply to all of C, C++, and Fortran). I also updated the information about what versions of OpenMP and OpenACC are supported and removed some redundant text from the Fortran manual to prevent it from getting out of sync on future updates, and inserted some cross-references to the new sections elsewhere. gcc/c-family/ChangeLog PR c/26154 * c.opt.urls: Regenerated. gcc/ChangeLog PR c/26154 * common.opt.urls: Regenerated. * doc/extend.texi (C Extensions): Adjust menu for new sections. (Attribute Syntax): Mention OpenMP directives. (Pragmas): Mention OpenMP and OpenACC directives. (OpenMP): New section. (OpenACC): New section. * doc/invoke.texi (Invoking GCC): Adjust menu for new section. (Option Summary): Move OpenMP and OpenACC options to their own category. (C Dialect Options): Move documentation for -foffload, -fopenacc, -fopenacc-dim, -fopenmp, -fopenmd-simd, and -fopenmp-target-simd-clone to... (OpenMP and OpenACC Options): ...this new section. Light copy-editing of the option descriptions. gcc/fortran/ChangeLog: PR c/26154 * gfortran.texi (Standards): Remove redundant info about OpenMP/OpenACC standard support. (OpenMP): Copy-editing and update version info. (OpenACC): Likewise. * lang.opt.urls: Regenerated. Diff: --- gcc/c-family/c.opt.urls | 8 +- gcc/common.opt.urls | 8 +- gcc/doc/extend.texi | 61 gcc/doc/invoke.texi | 240 -- gcc/fortran/gfortran.texi | 52 +- gcc/fortran/lang.opt.urls | 8 +- 6 files changed, 227 insertions(+), 150 deletions(-) diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls index 6c08b0ae052f..421cc08e2c72 100644 --- a/gcc/c-family/c.opt.urls +++ b/gcc/c-family/c.opt.urls @@ -1256,16 +1256,16 @@ fobjc-nilcheck UrlSuffix(gcc/Objective-C-and-Objective-C_002b_002b-Dialect-Options.html#index-fobjc-nilcheck) fopenacc -UrlSuffix(gcc/C-Dialect-Options.html#index-fopenacc) LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-fopenacc) +UrlSuffix(gcc/OpenMP-and-OpenACC-Options.html#index-fopenacc) LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-fopenacc) fopenacc-dim= -UrlSuffix(gcc/C-Dialect-Options.html#index-fopenacc-dim) +UrlSuffix(gcc/OpenMP-and-OpenACC-Options.html#index-fopenacc-dim) fopenmp -UrlSuffix(gcc/C-Dialect-Options.html#index-fopenmp) LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-fopenmp) +UrlSuffix(gcc/OpenMP-and-OpenACC-Options.html#index-fopenmp) LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-fopenmp) fopenmp-simd -UrlSuffix(gcc/C-Dialect-Options.html#index-fopenmp-simd) LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-fopenmp-simd) +UrlSuffix(gcc/OpenMP-and-OpenACC-Options.html#index-fopenmp-simd) LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-fopenmp-simd) foperator-names UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-fno-operator-names) diff --git a/gcc/common.opt.urls b/gcc/common.opt.urls index 577e00d7a276..79c322bed2b6 100644 --- a/gcc/common.opt.urls +++ b/gcc/common.opt.urls @@ -1005,19 +1005,19 @@ fnon-call-exceptions UrlSuffix(gcc/Code-Gen-Options.html#index-fnon-call-exceptions) foffload= -UrlSuffix(gcc/C-Dialect-Options.html#index-foffload) +UrlSuffix(gcc/OpenMP-and-OpenACC-Options.html#index-foffload) foffload-options= -UrlSuffix(gcc/C-Dialect-Options.html#index-foffload-options) +UrlSuffix(gcc/OpenMP-and-OpenACC-Options.html#index-foffload-options) fomit-frame-pointer UrlSuffix(gcc/Optimize-Options.html#index-fomit-frame-pointer) fopenmp-target-simd-clone -UrlSuffix(gcc/C-Dialect-Options.html#index-fopenmp-target-simd-clone) +UrlSuffix(gcc/OpenMP-and-OpenACC-Options.html#index-fopenmp-target-simd-clone) fopenmp-target-simd-clone= -UrlSuffix(gcc/C-Dialect-Options.html#index-fopenmp-target-simd-clone) +UrlSuffix(gcc/OpenMP-and-OpenACC-Options.html#index-fopenm
[gcc r14-11099] testsuite: arm: Mark pr81812.C as xfail for thumb1
https://gcc.gnu.org/g:0361b4c440f7990702eccafca31e871ae096198c commit r14-11099-g0361b4c440f7990702eccafca31e871ae096198c Author: Torbjörn SVENSSON Date: Sun Nov 10 20:15:13 2024 +0100 testsuite: arm: Mark pr81812.C as xfail for thumb1 Test fails for Cortex-M0 with: .../pr81812.C:6:8: error: generic thunk code fails for method 'virtual void ChildNode::_ZTv0_n12_NK9ChildNode5errorEz(...) const' which uses '...' According to PR108277, it's expected that thumb1 targets does not support empty virtual functions with ellipsis. gcc/testsuite/ChangeLog: * g++.dg/torture/pr81812.C: Add xfail for thumb1. Signed-off-by: Torbjörn SVENSSON (cherry picked from commit f111d8e20b671ee97d4ed835102839e44a2a2edc) Diff: --- gcc/testsuite/g++.dg/torture/pr81812.C | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcc/testsuite/g++.dg/torture/pr81812.C b/gcc/testsuite/g++.dg/torture/pr81812.C index d235e2375888..b5c621d2beb2 100644 --- a/gcc/testsuite/g++.dg/torture/pr81812.C +++ b/gcc/testsuite/g++.dg/torture/pr81812.C @@ -1,3 +1,5 @@ +// { dg-xfail-if "PR108277" { arm_thumb1 } } + struct Error { virtual void error(... ) const; };
[gcc r15-6311] libstdc++: Fix std::deque::insert(pos, first, last) undefined behaviour [PR118035]
https://gcc.gnu.org/g:b273e25e11c842a5729d0e03c85088cf5ba8e06c commit r15-6311-gb273e25e11c842a5729d0e03c85088cf5ba8e06c Author: Jonathan Wakely Date: Mon Dec 16 17:42:24 2024 + libstdc++: Fix std::deque::insert(pos, first, last) undefined behaviour [PR118035] Inserting an empty range into a std::deque results in undefined calls to either std::copy, std::copy_backward, std::move, or std::move_backward. We call those algos with invalid arguments where the output range is the same as the input range, e.g. std::copy(first, last, first) which violates the preconditions for the algorithms. This fix simply returns early if there's nothing to insert. Most callers already ensure that we don't even call _M_range_insert_aux with an empty range, but some callers don't. Rather than checking for n == 0 in each of the callers, this just does the check once and uses __builtin_expect to treat empty insertions as unlikely. libstdc++-v3/ChangeLog: PR libstdc++/118035 * include/bits/deque.tcc (_M_range_insert_aux): Return immediately if inserting an empty range. * testsuite/23_containers/deque/modifiers/insert/118035.cc: New test. Diff: --- libstdc++-v3/include/bits/deque.tcc| 3 +++ .../23_containers/deque/modifiers/insert/118035.cc | 26 ++ 2 files changed, 29 insertions(+) diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc index ee03c917a295..05929e9f812d 100644 --- a/libstdc++-v3/include/bits/deque.tcc +++ b/libstdc++-v3/include/bits/deque.tcc @@ -601,6 +601,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER std::forward_iterator_tag) { const size_type __n = std::distance(__first, __last); + if (__builtin_expect(__n == 0, 0)) + return; + if (__pos._M_cur == this->_M_impl._M_start._M_cur) { iterator __new_start = _M_reserve_elements_at_front(__n); diff --git a/libstdc++-v3/testsuite/23_containers/deque/modifiers/insert/118035.cc b/libstdc++-v3/testsuite/23_containers/deque/modifiers/insert/118035.cc new file mode 100644 index ..a37d3dc3d04c --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/deque/modifiers/insert/118035.cc @@ -0,0 +1,26 @@ +// { dg-do run } + +#include +#include + +struct Sparks +{ + Sparks& operator=(const Sparks& s) + { +VERIFY( this != &s ); // This town ain't big enough for the both of us. +return *this; + } +}; + +void +test_pr118035() +{ + std::deque d(3, Sparks()); + Sparks s[1]; + d.insert(d.begin() + 1, s, s); +} + +int main() +{ + test_pr118035(); +}
[gcc r15-6312] libstdc++: Fix -Wparentheses warning in Debug Mode macro
https://gcc.gnu.org/g:7d6dc2130970ccf6555d4e9f977515c6c20f7d2f commit r15-6312-g7d6dc2130970ccf6555d4e9f977515c6c20f7d2f Author: Jonathan Wakely Date: Fri Dec 13 16:53:06 2024 + libstdc++: Fix -Wparentheses warning in Debug Mode macro libstdc++-v3/ChangeLog: * include/debug/safe_local_iterator.h (_GLIBCXX_DEBUG_VERIFY_OPERANDS): Add parentheses to avoid -Wparentheses warning. Diff: --- libstdc++-v3/include/debug/safe_local_iterator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libstdc++-v3/include/debug/safe_local_iterator.h b/libstdc++-v3/include/debug/safe_local_iterator.h index b4da11d5ee13..1766cb7e72aa 100644 --- a/libstdc++-v3/include/debug/safe_local_iterator.h +++ b/libstdc++-v3/include/debug/safe_local_iterator.h @@ -32,7 +32,7 @@ #include #define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs) \ - _GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular() \ + _GLIBCXX_DEBUG_VERIFY((!_Lhs._M_singular() && !_Rhs._M_singular()) \ || (_Lhs._M_value_initialized() \ && _Rhs._M_value_initialized()),\ _M_message(__msg_iter_compare_bad) \
[gcc] Deleted branch 'mikael/heads/refactor_descriptor_v01' in namespace 'refs/users'
The branch 'mikael/heads/refactor_descriptor_v01' in namespace 'refs/users' was deleted. It previously pointed to: da5ac05fe243... Correction bornes descripteur null Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- da5ac05... Correction bornes descripteur null
[gcc r15-6309] middle-end/118062 - bogus lowering of vector compares
https://gcc.gnu.org/g:cfe1ad3c488693a10fafb39d68c8cabc6e48daa7 commit r15-6309-gcfe1ad3c488693a10fafb39d68c8cabc6e48daa7 Author: Richard Biener Date: Tue Dec 17 11:23:02 2024 +0100 middle-end/118062 - bogus lowering of vector compares The generic expand_vector_piecewise routine supports lowering of a vector operation to vector operations of smaller size. When computing the extract position from the larger vector it uses the element size in bits of the original result vector to determine the number of elements in the smaller vector. That is wrong when lowering a compare as the vector element size of a bool vector does not have to agree with that of the compare operand. The following simplifies this, fixing the error. PR middle-end/118062 * tree-vect-generic.cc (expand_vector_piecewise): Properly compute delta. Diff: --- gcc/tree-vect-generic.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/tree-vect-generic.cc b/gcc/tree-vect-generic.cc index 78f6e552cc7b..4b9cf734bdd1 100644 --- a/gcc/tree-vect-generic.cc +++ b/gcc/tree-vect-generic.cc @@ -292,7 +292,8 @@ expand_vector_piecewise (gimple_stmt_iterator *gsi, elem_op_func f, tree part_width = TYPE_SIZE (inner_type); tree index = bitsize_int (0); int nunits = nunits_for_known_piecewise_op (type); - int delta = tree_to_uhwi (part_width) / vector_element_bits (type); + int delta = (VECTOR_TYPE_P (inner_type) + ? nunits_for_known_piecewise_op (inner_type) : 1); int i; location_t loc = gimple_location (gsi_stmt (*gsi));