diff options
Diffstat (limited to 'gcc')
47 files changed, 827 insertions, 170 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0cee1ea..2314910 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,53 @@ +2025-04-03 Thomas Schwinge <tschwinge@baylibre.com> + + PR target/119573 + * config/nvptx/nvptx.cc (nvptx_encode_section_info): Don't set + 'DATA_AREA_CONST' for 'TREE_CONSTANT', or 'TREE_READONLY'. + (nvptx_asm_declare_constant_name): Use '.global' instead of + '.const'. + +2025-04-03 Peter Bergner <bergner@linux.ibm.com> + + PR target/119308 + * config/rs6000/rs6000-logue.cc (rs6000_output_function_epilogue): + Handle GCC COBOL for the tbtab lang field. + +2025-04-03 Sandra Loosemore <sloosemore@baylibre.com> + + * doc/extend.texi (Statement Attributes): Copy-edit the musttail + attribute documentation and correct the comment in the last + example. + +2025-04-03 Jan Hubicka <hubicka@ucw.cz> + + * config/i386/x86-tune-costs.h (ix86_size_cost): Fix sizes of move + instructions + +2025-04-03 Jakub Jelinek <jakub@redhat.com> + + PR cobol/119242 + * fold-const.h (native_encode_wide_int): Declare. + * fold-const.cc (native_encode_wide_int): New function. + (native_encode_int): Use it. + +2025-04-03 Xi Ruoyao <xry111@xry111.site> + + * config/loongarch/genopts/gen-evolution.awk: Avoid using gensub + that FreeBSD awk lacks. + +2025-04-03 Hongyu Wang <hongyu.wang@intel.com> + + PR target/119539 + * config/i386/i386.md (*<insn><mode>3_mask): Emit NF variant of + rotate when APX_NF enabled, and use force_lowpart_subreg. + (*<insn><mode>3_mask_1): Likewise. + +2025-04-03 Sandra Loosemore <sloosemore@baylibre.com> + + PR c/101440 + * doc/extend.texi (Common Function Attributes): Clean up some + confusing language in the description of the "access" attribute. + 2025-04-02 Sandra Loosemore <sloosemore@baylibre.com> GUO Yixuan <culu.gyx@gmail.com> diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 75f4546..c36e5b2 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20250403 +20250404 diff --git a/gcc/ada/libgnat/a-ngcoar.adb b/gcc/ada/libgnat/a-ngcoar.adb index 41c255f..9ce6caf 100644 --- a/gcc/ada/libgnat/a-ngcoar.adb +++ b/gcc/ada/libgnat/a-ngcoar.adb @@ -1058,19 +1058,21 @@ package body Ada.Numerics.Generic_Complex_Arrays is is N : constant Natural := Length (A); - -- For a Hermitian matrix C, we convert the eigenvalue problem to a - -- real symmetric one: if C = A + i * B, then the (N, N) complex + -- For a Hermitian matrix A, we convert the eigenvalue problem to a + -- real symmetric one: if A = X + i * Y, then the (N, N) complex -- eigenvalue problem: - -- (A + i * B) * (u + i * v) = Lambda * (u + i * v) + -- + -- (X + i * Y) * (u + i * v) = Lambda * (u + i * v) -- -- is equivalent to the (2 * N, 2 * N) real eigenvalue problem: - -- [ A, B ] [ u ] = Lambda * [ u ] - -- [ -B, A ] [ v ] [ v ] -- - -- Note that the (2 * N, 2 * N) matrix above is symmetric, as - -- Transpose (A) = A and Transpose (B) = -B if C is Hermitian. + -- [ X, -Y ] [ u ] = Lambda * [ u ] + -- [ Y, X ] [ v ] [ v ] + -- + -- Note that the (2 * N, 2 * N) matrix M above is symmetric, because + -- Transpose (X) = X and Transpose (Y) = -Y as A is Hermitian. - -- We solve this eigensystem using the real-valued algorithms. The final + -- We solve this eigensystem using the real-valued algorithm. The final -- result will have every eigenvalue twice, so in the sorted output we -- just pick every second value, with associated eigenvector u + i * v. @@ -1085,10 +1087,8 @@ package body Ada.Numerics.Generic_Complex_Arrays is C : constant Complex := (A (A'First (1) + (J - 1), A'First (2) + (K - 1))); begin - M (J, K) := Re (C); - M (J + N, K + N) := Re (C); - M (J + N, K) := Im (C); - M (J, K + N) := -Im (C); + M (J, K) := Re (C); M (J, K + N) := -Im (C); + M (J + N, K) := Im (C); M (J + N, K + N) := Re (C); end; end loop; end loop; @@ -1103,10 +1103,9 @@ package body Ada.Numerics.Generic_Complex_Arrays is for K in 1 .. N loop declare - Row : constant Integer := Vectors'First (2) + (K - 1); + Row : constant Integer := Vectors'First (1) + (K - 1); begin - Vectors (Row, Col) := - (Vecs (J * 2, Col), Vecs (J * 2, Col + N)); + Vectors (Row, Col) := (Vecs (K, 2 * J), Vecs (K + N, 2 * J)); end; end loop; end; @@ -1118,13 +1117,14 @@ package body Ada.Numerics.Generic_Complex_Arrays is ----------------- function Eigenvalues (A : Complex_Matrix) return Real_Vector is - -- See Eigensystem for a description of the algorithm - N : constant Natural := Length (A); - R : Real_Vector (A'Range (1)); + + -- See Eigensystem for a description of the algorithm M : Real_Matrix (1 .. 2 * N, 1 .. 2 * N); + R : Real_Vector (A'Range (1)); Vals : Real_Vector (1 .. 2 * N); + begin for J in 1 .. N loop for K in 1 .. N loop @@ -1132,10 +1132,8 @@ package body Ada.Numerics.Generic_Complex_Arrays is C : constant Complex := (A (A'First (1) + (J - 1), A'First (2) + (K - 1))); begin - M (J, K) := Re (C); - M (J + N, K + N) := Re (C); - M (J + N, K) := Im (C); - M (J, K + N) := -Im (C); + M (J, K) := Re (C); M (J, K + N) := -Im (C); + M (J + N, K) := Im (C); M (J + N, K + N) := Re (C); end; end loop; end loop; diff --git a/gcc/ada/libgnat/a-ngrear.adb b/gcc/ada/libgnat/a-ngrear.adb index e7b1bcd..524b4a0 100644 --- a/gcc/ada/libgnat/a-ngrear.adb +++ b/gcc/ada/libgnat/a-ngrear.adb @@ -85,7 +85,7 @@ package body Ada.Numerics.Generic_Real_Arrays is function Is_Symmetric (A : Real_Matrix) return Boolean is (Transpose (A) = A); - -- Return True iff A is symmetric, see RM G.3.1 (90). + -- Return True iff A is symmetric, see RM G.3.1 (90) function Is_Tiny (Value, Compared_To : Real) return Boolean is (abs Compared_To + 100.0 * abs Value = abs Compared_To); @@ -104,7 +104,7 @@ package body Ada.Numerics.Generic_Real_Arrays is -- not a square matrix, and otherwise returns its length. procedure Rotate (X, Y : in out Real; Sin, Tau : Real); - -- Perform a Givens rotation + -- Perform a Givens rotation of angle Theta given by sin and sin/(1 + cos) procedure Sort_Eigensystem (Values : in out Real_Vector; @@ -525,13 +525,13 @@ package body Ada.Numerics.Generic_Real_Arrays is Vectors : out Real_Matrix; Compute_Vectors : Boolean) is - -- This subprogram uses Carl Gustav Jacob Jacobi's iterative method - -- for computing eigenvalues and eigenvectors and is based on + -- This subprogram uses Carl Gustav Jacob Jacobi's cyclic iterative + -- method for computing eigenvalues and eigenvectors and is based on -- Rutishauser's implementation. -- The given real symmetric matrix is transformed iteratively to -- diagonal form through a sequence of appropriately chosen elementary - -- orthogonal transformations, called Jacobi rotations here. + -- orthogonal transformations, called Jacobi rotations. -- The Jacobi method produces a systematic decrease of the sum of the -- squares of off-diagonal elements. Convergence to zero is quadratic, @@ -542,41 +542,44 @@ package body Ada.Numerics.Generic_Real_Arrays is -- best choice here, even though for large matrices other methods will -- be significantly more efficient in both time and space. - -- While the eigensystem computations are absolutely foolproof for all + -- While the eigensystem computation is absolutely foolproof for all -- real symmetric matrices, in presence of invalid values, or similar - -- exceptional situations it might not. In such cases the results cannot - -- be trusted and Constraint_Error is raised. + -- exceptional situations, it may not be. In such cases, the results + -- cannot be trusted and Constraint_Error is raised. -- Note: this implementation needs temporary storage for 2 * N + N**2 -- values of type Real. - Max_Iterations : constant := 50; - N : constant Natural := Length (A); + Max_Iterations : constant := 50; + N : constant Natural := Length (A); subtype Square_Matrix is Real_Matrix (1 .. N, 1 .. N); - -- In order to annihilate the M (Row, Col) element, the - -- rotation parameters Cos and Sin are computed as - -- follows: + -- In order to annihilate the M (Row, Col) element, the rotation angle + -- Theta is chosen as follows: - -- Theta = Cot (2.0 * Phi) - -- = (Diag (Col) - Diag (Row)) / (2.0 * M (Row, Col)) + -- Cot (2.0 * Theta) = (Diag (Col) - Diag (Row)) / (2.0 * M (Row, Col)) - -- Then Tan (Phi) as the smaller root (in modulus) of + -- If C = Cot (2.0 * Theta), then Tan (Theta) is computed as the smaller + -- root (in modulus) of: - -- T**2 + 2 * T * Theta = 1 (or 0.5 / Theta, if Theta is large) + -- X**2 + 2 * C * X - 1 = 0 - function Compute_Tan (Theta : Real) return Real is - (Real'Copy_Sign (1.0 / (abs Theta + Sqrt (1.0 + Theta**2)), Theta)); + -- or else as 0.5 / C, if C is large. + + function Compute_Tan (C : Real) return Real is + (Real'Copy_Sign (1.0 / (abs C + Sqrt (1.0 + C**2)), C)); function Compute_Tan (P, H : Real) return Real is - (if Is_Tiny (P, Compared_To => H) then P / H - else Compute_Tan (Theta => H / (2.0 * P))); + (if Is_Tiny (P, Compared_To => H) + then P / H + else Compute_Tan (C => H / (2.0 * P))); pragma Annotate (CodePeer, False_Positive, "divide by zero", "H, P /= 0"); function Sum_Strict_Upper (M : Square_Matrix) return Real; - -- Return the sum of all elements in the strict upper triangle of M + -- Return the sum of the absolute value of all the elements in the + -- strict upper triangle of M. ---------------------- -- Sum_Strict_Upper -- @@ -595,11 +598,13 @@ package body Ada.Numerics.Generic_Real_Arrays is return Sum; end Sum_Strict_Upper; + -- Local variables + M : Square_Matrix := A; -- Work space for solving eigensystem - Threshold : Real; - Sum : Real; Diag : Real_Vector (1 .. N); Diag_Adj : Real_Vector (1 .. N); + Sum : Real; + Threshold : Real; -- The vector Diag_Adj indicates the amount of change in each value, -- while Diag tracks the value itself and Values holds the values as @@ -621,22 +626,24 @@ package body Ada.Numerics.Generic_Real_Arrays is raise Constraint_Error with "matrix not symmetric"; end if; + Values := Diagonal (M); + -- Note: Only the locally declared matrix M and vectors (Diag, Diag_Adj) -- have lower bound equal to 1. The Vectors matrix may have -- different bounds, so take care indexing elements. Assignment -- as a whole is fine as sliding is automatic in that case. - Vectors := (if not Compute_Vectors then [1 .. 0 => [1 .. 0 => 0.0]] - else Unit_Matrix (Vectors'Length (1), Vectors'Length (2))); - Values := Diagonal (M); + Vectors := (if Compute_Vectors + then Unit_Matrix (N) + else [1 .. 0 => [1 .. 0 => 0.0]]); Sweep : for Iteration in 1 .. Max_Iterations loop - -- The first three iterations, perform rotation for any non-zero - -- element. After this, rotate only for those that are not much - -- smaller than the average off-diagnal element. After the fifth - -- iteration, additionally zero out off-diagonal elements that are - -- very small compared to elements on the diagonal with the same + -- During the first three iterations, perform the rotation only for + -- elements that are not much smaller than the average off-diagonal + -- element. After this, rotate for any non-zero elements. After the + -- fifth iteration, additionally zero out off-diagonal elements that + -- are very small compared to elements on the diagonal with the same -- column or row index. Sum := Sum_Strict_Upper (M); @@ -645,8 +652,8 @@ package body Ada.Numerics.Generic_Real_Arrays is Threshold := (if Iteration < 4 then 0.2 * Sum / Real (N**2) else 0.0); - -- Iterate over all off-diagonal elements, rotating any that have - -- an absolute value that exceeds the threshold. + -- Iterate over all off-diagonal elements, rotating any that have an + -- absolute value that exceeds the threshold. Diag := Values; Diag_Adj := [others => 0.0]; -- Accumulates adjustments to Diag @@ -654,11 +661,11 @@ package body Ada.Numerics.Generic_Real_Arrays is for Row in 1 .. N - 1 loop for Col in Row + 1 .. N loop - -- If, before the rotation M (Row, Col) is tiny compared to + -- If, before the rotation, M (Row, Col) is tiny compared to -- Diag (Row) and Diag (Col), rotation is skipped. This is -- meaningful, as it produces no larger error than would be -- produced anyhow if the rotation had been performed. - -- Suppress this optimization in the first four sweeps, so + -- Suppress this optimization in the first four iterations, so -- that this procedure can be used for computing eigenvectors -- of perturbed diagonal matrices. @@ -670,8 +677,8 @@ package body Ada.Numerics.Generic_Real_Arrays is elsif abs M (Row, Col) > Threshold then Perform_Rotation : declare - Tan : constant Real := Compute_Tan (M (Row, Col), - Diag (Col) - Diag (Row)); + Tan : constant Real := + Compute_Tan (M (Row, Col), Diag (Col) - Diag (Row)); Cos : constant Real := 1.0 / Sqrt (1.0 + Tan**2); Sin : constant Real := Tan * Cos; Tau : constant Real := Sin / (1.0 + Cos); @@ -710,7 +717,7 @@ package body Ada.Numerics.Generic_Real_Arrays is Values := Values + Diag_Adj; end loop Sweep; - -- All normal matrices with valid values should converge perfectly. + -- All normal matrices with valid values should converge perfectly if Sum /= 0.0 then raise Constraint_Error with "eigensystem solution does not converge"; diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 829de00..5e7bff8 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2025-04-03 Jakub Jelinek <jakub@redhat.com> + + * c.opt.urls: Regenerate. + 2025-03-30 Sandra Loosemore <sloosemore@baylibre.com> * c.opt.urls: Regenerate. diff --git a/gcc/cfgrtl.cc b/gcc/cfgrtl.cc index d206c0d..310028f 100644 --- a/gcc/cfgrtl.cc +++ b/gcc/cfgrtl.cc @@ -3213,6 +3213,16 @@ purge_dead_edges (basic_block bb) && ! may_trap_p (XEXP (eqnote, 0)))) remove_note (insn, note); } + /* A tail call cannot trap either. The tailc/musttail pass could have + allowed a tail call if it could throw internally, but perform no + actual statements and then caused the exception to be thrown externally + in the hope that it is cleaned up later. If it is not, just + remove REG_EH_REGION note. While the call maybe can throw, the + current function's frame will not be there anymore when it does. */ + if (CALL_P (insn) + && SIBLING_CALL_P (insn) + && (note = find_reg_note (insn, REG_EH_REGION, NULL))) + remove_note (insn, note); /* Cleanup abnormal edges caused by exceptions or non-local gotos. */ for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) diff --git a/gcc/cobol/ChangeLog b/gcc/cobol/ChangeLog index e06e789..0b85ff2 100644 --- a/gcc/cobol/ChangeLog +++ b/gcc/cobol/ChangeLog @@ -1,3 +1,9 @@ +2025-04-03 Jakub Jelinek <jakub@redhat.com> + + PR cobol/119242 + * genapi.cc (binary_initial_from_float128): Use + native_encode_wide_int. + 2025-04-02 Bob Dubner <rdubner@symas.com> PR cobol/119521 diff --git a/gcc/cobol/cobol1.cc b/gcc/cobol/cobol1.cc index 0d07c46..d175ab1 100644 --- a/gcc/cobol/cobol1.cc +++ b/gcc/cobol/cobol1.cc @@ -646,6 +646,22 @@ cobol_get_sarif_source_language(const char *) return "cobol"; } +bool +cobol_langhook_post_options(const char**) + { + // This flag, when set to 0, results in calls to gg_exit working properly. + // I don't know why it is necessary. There is something going on with the + // definition of __gg__data_return_code in constants.cc, and with how it + // is used through var_decl_return_code in genapi.cc. Without it, the value + // delivered to exit@PLT is zero, and not __gg__data_return_code + // Dubner, 2025-04-04. + flag_strict_aliasing = 0; + + /* Returning false means that the backend should be used. */ + return false; + } + + #undef LANG_HOOKS_BUILTIN_FUNCTION #undef LANG_HOOKS_GETDECLS #undef LANG_HOOKS_GLOBAL_BINDINGS_P @@ -660,6 +676,7 @@ cobol_get_sarif_source_language(const char *) ////#undef LANG_HOOKS_TYPE_FOR_SIZE #undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME #undef LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE +#undef LANG_HOOKS_POST_OPTIONS // We use GCC in the name, not GNU, as others do, // because "GnuCOBOL" refers to a different GNU project. @@ -685,6 +702,8 @@ cobol_get_sarif_source_language(const char *) #define LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE cobol_get_sarif_source_language +#define LANG_HOOKS_POST_OPTIONS cobol_langhook_post_options + struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; #include "gt-cobol-cobol1.h" diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index a0da647..fbe0bbc 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -8806,6 +8806,10 @@ static void set_user_status(struct cbl_file_t *file) { // This routine sets the user_status, if any, to the cblc_file_t::status + + // We have to do it this way, because in the case where the file->user_status + // is in linkage, the memory addresses can end up pointing to the wrong + // places if(file->user_status) { cbl_field_t *user_status = cbl_field_of(symbol_at(file->user_status)); @@ -10111,6 +10115,13 @@ parser_intrinsic_subst( cbl_field_t *f, SHOW_PARSE { SHOW_PARSE_HEADER + SHOW_PARSE_FIELD(" TO ", f) + for(size_t i=0; i<argc; i++) + { + SHOW_PARSE_INDENT + SHOW_PARSE_FIELD(" ", argv[i].orig.field) + SHOW_PARSE_FIELD(" ", argv[i].replacement.field) + } SHOW_PARSE_END } TRACE1 @@ -15908,12 +15919,12 @@ psa_global(cbl_field_t *new_var) if( strcmp(new_var->name, "RETURN-CODE") == 0 ) { - strcpy(ach, "__gg___11_return_code6"); + strcpy(ach, "__gg__return_code"); } if( strcmp(new_var->name, "UPSI-0") == 0 ) { - strcpy(ach, "__gg___6_upsi_04"); + strcpy(ach, "__gg__upsi"); } new_var->var_decl_node = gg_declare_variable(cblc_field_type_node, ach, NULL, vs_external_reference); @@ -16156,6 +16167,10 @@ psa_FldLiteralA(struct cbl_field_t *field ) field->data.initial, NULL_TREE, field->var_decl_node); + TREE_READONLY(field->var_decl_node) = 1; + TREE_USED(field->var_decl_node) = 1; + TREE_STATIC(field->var_decl_node) = 1; + DECL_PRESERVE_P (field->var_decl_node) = 1; nvar += 1; } TRACE1 diff --git a/gcc/cobol/gengen.cc b/gcc/cobol/gengen.cc index ffb64c8..e7a4e3c 100644 --- a/gcc/cobol/gengen.cc +++ b/gcc/cobol/gengen.cc @@ -375,6 +375,10 @@ show_type(tree type) static char ach[1024]; switch( TREE_CODE(type) ) { + case POINTER_TYPE: + sprintf(ach, "POINTER"); + break; + case VOID_TYPE: sprintf(ach, "VOID"); break; @@ -2548,6 +2552,10 @@ gg_define_function_with_no_parameters(tree return_type, DECL_CONTEXT (function_decl) = gg_trans_unit.trans_unit_decl; TREE_PUBLIC(function_decl) = 0; + // This function is file static, but nobody calls it, so without + // intervention -O1+ optimizations will discard it. + DECL_PRESERVE_P (function_decl) = 1; + // Append this function to the list of functions and variables // associated with the computation module. gg_append_var_decl(function_decl); @@ -3358,8 +3366,8 @@ gg_array_of_size_t( size_t N, size_t *values) tree gg_array_of_bytes( size_t N, unsigned char *values) { - tree retval = gg_define_variable(build_pointer_type(UCHAR)); - gg_assign(retval, gg_cast(build_pointer_type(UCHAR), gg_malloc( build_int_cst_type(UCHAR, N * sizeof(unsigned char))))); + tree retval = gg_define_variable(UCHAR_P); + gg_assign(retval, gg_cast(UCHAR_P, gg_malloc( build_int_cst_type(SIZE_T, N * sizeof(unsigned char))))); for(size_t i=0; i<N; i++) { gg_assign(gg_array_value(retval, i), build_int_cst_type(UCHAR, values[i])); diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index f38e3db..4f8380c4 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -21883,7 +21883,11 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno, case SYMBOL_REF: if (x86_64_immediate_operand (x, VOIDmode)) *total = 0; - else + else if (TARGET_64BIT && x86_64_zext_immediate_operand (x, VOIDmode)) + /* Consider the zext constants slightly more expensive, as they + can't appear in most instructions. */ + *total = 1; + else /* movabsq is slightly more expensive than a simple instruction. */ *total = COSTS_N_INSNS (1) + 1; return true; diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc index 022037f..de0ce5d 100644 --- a/gcc/config/nvptx/nvptx.cc +++ b/gcc/config/nvptx/nvptx.cc @@ -470,9 +470,7 @@ nvptx_encode_section_info (tree decl, rtx rtl, int first) { nvptx_data_area area = DATA_AREA_GENERIC; - if (TREE_CONSTANT (decl)) - area = DATA_AREA_CONST; - else if (VAR_P (decl)) + if (VAR_P (decl)) { if (lookup_attribute ("shared", DECL_ATTRIBUTES (decl))) { @@ -482,7 +480,7 @@ nvptx_encode_section_info (tree decl, rtx rtl, int first) " memory is not supported", decl); } else - area = TREE_READONLY (decl) ? DATA_AREA_CONST : DATA_AREA_GLOBAL; + area = DATA_AREA_GLOBAL; } SET_SYMBOL_DATA_AREA (XEXP (rtl, 0), area); @@ -2597,7 +2595,7 @@ nvptx_asm_declare_constant_name (FILE *file, const char *name, fprintf (file, "\t"); tree type = TREE_TYPE (exp); - nvptx_assemble_decl_begin (file, name, ".const", type, obj_size, + nvptx_assemble_decl_begin (file, name, ".global", type, obj_size, TYPE_ALIGN (type)); } diff --git a/gcc/config/rs6000/rs6000-logue.cc b/gcc/config/rs6000/rs6000-logue.cc index 52f44b1..5377ad6c 100644 --- a/gcc/config/rs6000/rs6000-logue.cc +++ b/gcc/config/rs6000/rs6000-logue.cc @@ -5351,6 +5351,8 @@ rs6000_output_function_epilogue (FILE *file) i = 1; else if (! strcmp (language_string, "GNU Ada")) i = 3; + else if (! strcmp (language_string, "GCC COBOL")) + i = 7; else if (! strcmp (language_string, "GNU Modula-2")) i = 8; else if (lang_GNU_CXX () diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b605560..9342f9f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,28 @@ +2025-04-03 Patrick Palka <ppalka@redhat.com> + + PR c++/119387 + * constexpr.cc (p2280_active_p): New. + (cxx_eval_constant_expression) <case VAR_DECL>: Use it to + restrict P2280 relaxations. + <case PARM_DECL>: Likewise. + +2025-04-03 Jason Merrill <jason@redhat.com> + + * module.cc (module_state::read_cluster) + (post_load_processing): Clear DECL_EXTERNAL if DECL_COMDAT. + +2025-04-03 Jason Merrill <jason@redhat.com> + + * call.cc (add_candidates): Re-lookup ne_fns if we move into + another namespace. + +2025-04-03 Andrew Pinski <quic_apinski@quicinc.com> + Jakub Jelinek <jakub@redhat.com> + + PR c++/119563 + * call.cc (build_list_conv): Fix a typo in loop gathering + summary information from subsubconvs. + 2025-04-02 Sandra Loosemore <sloosemore@baylibre.com> PR middle-end/118965 diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index d853362..6caac89 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -6673,6 +6673,7 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args, bool check_list_ctor = false; bool check_converting = false; unification_kind_t strict; + tree ne_context = NULL_TREE; tree ne_fns = NULL_TREE; if (!fns) @@ -6719,6 +6720,7 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args, tree ne_name = ovl_op_identifier (false, NE_EXPR); if (DECL_CLASS_SCOPE_P (fn)) { + ne_context = DECL_CONTEXT (fn); ne_fns = lookup_fnfields (TREE_TYPE ((*args)[0]), ne_name, 1, tf_none); if (ne_fns == error_mark_node || ne_fns == NULL_TREE) @@ -6728,8 +6730,9 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args, } else { - tree context = decl_namespace_context (fn); - ne_fns = lookup_qualified_name (context, ne_name, LOOK_want::NORMAL, + ne_context = decl_namespace_context (fn); + ne_fns = lookup_qualified_name (ne_context, ne_name, + LOOK_want::NORMAL, /*complain*/false); if (ne_fns == error_mark_node || !is_overloaded_fn (ne_fns)) @@ -6828,8 +6831,26 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args, /* When considering reversed operator==, if there's a corresponding operator!= in the same scope, it's not a rewrite target. */ - if (ne_fns) + if (ne_context) { + if (TREE_CODE (ne_context) == NAMESPACE_DECL) + { + /* With argument-dependent lookup, fns can span multiple + namespaces; make sure we look in the fn's namespace for a + corresponding operator!=. */ + tree fn_ns = decl_namespace_context (fn); + if (fn_ns != ne_context) + { + ne_context = fn_ns; + tree ne_name = ovl_op_identifier (false, NE_EXPR); + ne_fns = lookup_qualified_name (ne_context, ne_name, + LOOK_want::NORMAL, + /*complain*/false); + if (ne_fns == error_mark_node + || !is_overloaded_fn (ne_fns)) + ne_fns = NULL_TREE; + } + } bool found = false; for (lkp_iterator ne (ne_fns); !found && ne; ++ne) if (0 && !ne.using_p () diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 4820bcc..9a57f48 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -1294,6 +1294,22 @@ struct constexpr_ctx { mce_value manifestly_const_eval; }; +/* True if the constexpr relaxations afforded by P2280R4 for unknown + references and objects are in effect. */ + +static bool +p2280_active_p (const constexpr_ctx *ctx) +{ + if (ctx->manifestly_const_eval != mce_true) + /* Disable these relaxations during speculative constexpr folding, + as it can significantly increase compile time/memory use + (PR119387). */ + return false; + + /* P2280R4 was accepted as a DR against C++11. */ + return cxx_dialect >= cxx11; +} + /* Remove T from the global values map, checking for attempts to destroy a value that has already finished its lifetime. */ @@ -7792,7 +7808,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, r = TARGET_EXPR_INITIAL (r); if (DECL_P (r) /* P2280 allows references to unknown. */ - && !(VAR_P (t) && TYPE_REF_P (TREE_TYPE (t)))) + && !(p2280_active_p (ctx) && VAR_P (t) && TYPE_REF_P (TREE_TYPE (t)))) { if (!ctx->quiet) non_const_var_error (loc, r, /*fundef_p*/false); @@ -7844,9 +7860,9 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, r = build_constructor (TREE_TYPE (t), NULL); TREE_CONSTANT (r) = true; } - else if (TYPE_REF_P (TREE_TYPE (t))) + else if (p2280_active_p (ctx) && TYPE_REF_P (TREE_TYPE (t))) /* P2280 allows references to unknown... */; - else if (is_this_parameter (t)) + else if (p2280_active_p (ctx) && is_this_parameter (t)) /* ...as well as the this pointer. */; else { diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index ed70bb0..f0a54b6 100644 --- a/gcc/cp/lambda.cc +++ b/gcc/cp/lambda.cc @@ -59,7 +59,13 @@ build_lambda_object (tree lambda_expr) vec<constructor_elt, va_gc> *elts = NULL; tree node, expr, type; - if (processing_template_decl || lambda_expr == error_mark_node) + if (processing_template_decl && !in_template_context + && current_binding_level->requires_expression) + /* As in cp_parser_lambda_expression, don't get confused by + cp_parser_requires_expression setting processing_template_decl. In that + case we want to return the result of finish_compound_literal, to avoid + tsubst_lambda_expr. */; + else if (processing_template_decl || lambda_expr == error_mark_node) return lambda_expr; /* Make sure any error messages refer to the lambda-introducer. */ diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index ce22b2e..89deabb 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -16679,6 +16679,15 @@ module_state::read_cluster (unsigned snum) #endif cfun->returns_struct = aggr; expand_or_defer_fn (decl); + + /* If we first see this function after at_eof, it doesn't get + note_vague_linkage_fn from tentative_decl_linkage, so the loop in + c_parse_final_cleanups won't consider it. But with DECL_COMDAT we + can just clear DECL_EXTERNAL and let cgraph decide. + FIXME handle this outside module.cc after GCC 15. */ + if (at_eof && DECL_COMDAT (decl) && DECL_EXTERNAL (decl) + && DECL_NOT_REALLY_EXTERN (decl)) + DECL_EXTERNAL (decl) = false; } } @@ -19159,6 +19168,10 @@ post_load_processing () gcc_checking_assert (DECL_MAYBE_IN_CHARGE_CDTOR_P (decl)); expand_or_defer_fn (decl); + /* As in module_state::read_cluster. */ + if (at_eof && DECL_COMDAT (decl) && DECL_EXTERNAL (decl) + && DECL_NOT_REALLY_EXTERN (decl)) + DECL_EXTERNAL (decl) = false; } cfun = old_cfun; diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 53e6237..812a7c5 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -11736,21 +11736,34 @@ cp_parser_lambda_expression (cp_parser* parser) if (cp_parser_error_occurred (parser)) return error_mark_node; - type = begin_lambda_type (lambda_expr); - if (type == error_mark_node) - return error_mark_node; + { + /* OK, this is a bit tricksy. cp_parser_requires_expression sets + processing_template_decl to make checking more normal, but that confuses + lambda parsing terribly. In non-template context, we want to parse the + lambda once and not tsubst_lambda_expr. So in that case, clear + processing_template_decl now, and restore it before the call to + build_lambda_object; that way we end up with what looks like a templatey + functional cast to the closure type, which is suitable for the + requires-expression tsubst_expr. This is PR99546 and friends. */ + processing_template_decl_sentinel ptds (/*reset*/false); + if (processing_template_decl && !in_template_context + && current_binding_level->requires_expression) + processing_template_decl = 0; + + type = begin_lambda_type (lambda_expr); + if (type == error_mark_node) + return error_mark_node; - record_lambda_scope (lambda_expr); - record_lambda_scope_discriminator (lambda_expr); + record_lambda_scope (lambda_expr); + record_lambda_scope_discriminator (lambda_expr); - /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */ - determine_visibility (TYPE_NAME (type)); + /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */ + determine_visibility (TYPE_NAME (type)); - /* Now that we've started the type, add the capture fields for any - explicit captures. */ - register_capture_members (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr)); + /* Now that we've started the type, add the capture fields for any + explicit captures. */ + register_capture_members (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr)); - { /* Inside the class, surrounding template-parameter-lists do not apply. */ unsigned int saved_num_template_parameter_lists = parser->num_template_parameter_lists; diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 7d8beb8..a10ef34 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -4755,6 +4755,7 @@ finish_id_expression_1 (tree id_expression, body, except inside an unevaluated context (i.e. decltype). */ if (TREE_CODE (decl) == PARM_DECL && DECL_CONTEXT (decl) == NULL_TREE + && !CONSTRAINT_VAR_P (decl) && !cp_unevaluated_operand && !processing_contract_condition && !processing_omp_trait_property_expr) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 4302df7..16ad83f 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -9314,7 +9314,7 @@ The @code{gnu::musttail} or @code{clang::musttail} standard attribute or @code{musttail} GNU attribute can be applied to a @code{return} statement with a return-value expression that is a function call. It asserts that the call must be a tail call that does not allocate extra stack space, so it is -safe to use tail recursion to implement long running loops. +safe to use tail recursion to implement long-running loops. @smallexample [[gnu::musttail]] return foo(); @@ -9324,11 +9324,11 @@ safe to use tail recursion to implement long running loops. __attribute__((musttail)) return bar(); @end smallexample -If the compiler cannot generate a @code{musttail} tail call it will report -an error. On some targets tail calls may never be supported. -The user asserts for @code{musttail} tail calls that lifetime of automatic +If the compiler cannot generate a @code{musttail} tail call it reports +an error. On some targets, tail calls may not be supported at all. +The @code{musttail} attribute asserts that the lifetime of automatic variables, function parameters and temporaries (unless they have non-trivial -destruction) can end before the actual call instruction and that any access +destruction) can end before the actual call instruction, and that any access to those from inside of the called function results is considered undefined behavior. Enabling @option{-O1} or @option{-O2} can improve the success of tail calls. @@ -9344,9 +9344,9 @@ baz (int *x) if (*x == 1) @{ int a = 42; - /* The call will be tail called (would not be without the - attribute), dereferencing the pointer in the callee is - undefined behavior and there will be a warning emitted + /* The call is a tail call (would not be without the + attribute). Dereferencing the pointer in the callee is + undefined behavior, and there is a warning emitted for this by default (@option{-Wmusttail-local-addr}). */ [[gnu::musttail]] return foo (&a); @} @@ -9354,9 +9354,9 @@ baz (int *x) @{ int a = 42; bar (&a); - /* The call will be tail called (would not be without the - attribute), if bar stores the pointer anywhere, dereferencing - it in foo will be undefined behavior and there will be a warning + /* The call is a tail call (would not be without the + attribute). If bar stores the pointer anywhere, dereferencing + it in foo is undefined behavior. There is a warning emitted for this with @option{-Wextra}, which implies @option{-Wmaybe-musttail-local-addr}. */ [[gnu::musttail]] return foo (nullptr); @@ -9365,8 +9365,8 @@ baz (int *x) @{ S s; /* The s variable requires non-trivial destruction which ought - to be performed after the foo call returns, so this will - be rejected. */ + to be performed after the foo call returns, so this is + rejected. */ [[gnu::musttail]] return foo (&s.s); @} @} @@ -9374,9 +9374,9 @@ baz (int *x) To avoid the @option{-Wmaybe-musttail-local-addr} warning in the above @code{*x == 2} case and similar code, consider defining the -maybe escaped variables in a separate scope which will end before the -return statement if possible to make it clear that the variable is not -live during the call. So +maybe-escaped variables in a separate scope that ends before the +return statement, if that is possible, to make it clear that the +variable is not live during the call. So: @smallexample else if (*x == 2) @@ -9385,17 +9385,17 @@ live during the call. So int a = 42; bar (&a); @} - /* The call will be tail called (would not be without the - attribute), if bar stores the pointer anywhere, dereferencing - it in foo will be undefined behavior and there will be a warning - emitted for this with @option{-Wextra}, which implies - @option{-Wmaybe-musttail-local-addr}. */ + /* The call is a tail call (would not be without the + attribute). If bar stores the pointer anywhere, dereferencing + it in foo is undefined behavior even without tail call + optimization, and there is no warning. */ [[gnu::musttail]] return foo (nullptr); @} @end smallexample -in this case. That is not possible if it is function argument which -is address taken because those are in scope for the whole function. +It is not possible to avoid the warning in this way if the maybe-escaped +variable is a function argument, because those are in scope +for the whole function. @end table @node Attribute Syntax diff --git a/gcc/lto-opts.cc b/gcc/lto-opts.cc index dee1caa..3959598 100644 --- a/gcc/lto-opts.cc +++ b/gcc/lto-opts.cc @@ -82,31 +82,32 @@ lto_write_options (void) subject of merging in lto-wrapper. */ if (!OPTION_SET_P (flag_pic) && !OPTION_SET_P (flag_pie)) { - append_to_collect_gcc_options (&temporary_obstack, &first_p, - global_options.x_flag_pic == 2 - ? "-fPIC" - : global_options.x_flag_pic == 1 - ? "-fpic" - : global_options.x_flag_pie == 2 - ? "-fPIE" - : global_options.x_flag_pie == 1 - ? "-fpie" - : "-fno-pie"); + const char *pic = "-fno-pie"; + if (global_options.x_flag_pie == 2) + pic = "-fPIE"; + else if (global_options.x_flag_pie == 1) + pic = "-fpie"; + else if (global_options.x_flag_pic == 2) + pic = "-fPIC"; + else if (global_options.x_flag_pic == 1) + pic = "-fpic"; + append_to_collect_gcc_options (&temporary_obstack, &first_p, pic); } if (!OPTION_SET_P (flag_cf_protection)) { - append_to_collect_gcc_options ( - &temporary_obstack, &first_p, - global_options.x_flag_cf_protection == CF_NONE - ? "-fcf-protection=none" - : global_options.x_flag_cf_protection == CF_FULL - ? "-fcf-protection=full" - : global_options.x_flag_cf_protection == CF_BRANCH - ? "-fcf-protection=branch" - : global_options.x_flag_cf_protection == CF_RETURN - ? "-fcf-protection=return" - : ""); + const char *cf_protection = NULL; + switch (global_options.x_flag_cf_protection) + { + case CF_NONE: cf_protection = "-fcf-protection=none"; break; + case CF_FULL: cf_protection = "-fcf-protection=full"; break; + case CF_BRANCH: cf_protection = "-fcf-protection=branch"; break; + case CF_RETURN: cf_protection = "-fcf-protection=return"; break; + default: break; + } + if (cf_protection) + append_to_collect_gcc_options (&temporary_obstack, &first_p, + cf_protection); } /* If debug info is enabled append -g. */ diff --git a/gcc/profile.cc b/gcc/profile.cc index 550c85b97..6234dd2 100644 --- a/gcc/profile.cc +++ b/gcc/profile.cc @@ -1341,9 +1341,10 @@ branch_prob (bool thunk) ignored_edges++; } /* Ignore edges after musttail calls. */ - if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)) + if (cfun->has_musttail + && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)) { - gimple_stmt_iterator gsi = gsi_last_bb (e->src); + gimple_stmt_iterator gsi = gsi_last_nondebug_bb (e->src); gimple *stmt = gsi_stmt (gsi); if (stmt && is_gimple_call (stmt) diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc index 7ad67af..86a5e47 100644 --- a/gcc/rtlanal.cc +++ b/gcc/rtlanal.cc @@ -5772,7 +5772,7 @@ pattern_cost (rtx pat, bool speed) return 0; cost = set_src_cost (SET_SRC (set), GET_MODE (SET_DEST (set)), speed); - return cost > 0 ? cost : COSTS_N_INSNS (1); + return MAX (COSTS_N_INSNS (1), cost); } /* Calculate the cost of a single instruction. A return value of zero diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 422b365..9bc53e0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,106 @@ +2025-04-03 Thomas Schwinge <tschwinge@baylibre.com> + + PR target/119573 + * gcc.c-torture/compile/pr46534.c: Don't 'dg-skip-if' nvptx. + * gcc.target/nvptx/decl.c: Adjust. + +2025-04-03 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp2a/spaceship-rewrite6.C: New test. + +2025-04-03 Victor Do Nascimento <victor.donascimento@arm.com> + + PR testsuite/118597 + * gcc.dg/vect/vect-fncall-mask.c: Update test directives. + +2025-04-03 Bob Dubner <rdubner@symas.com> + + * cobol.dg/group2/INSPECT_BACKWARD_REPLACING_LEADING.cob: New testcase. + * cobol.dg/group2/INSPECT_BACKWARD_REPLACING_TRAILING.cob: Likewise. + * cobol.dg/group2/INSPECT_BACKWARD_simple_CONVERTING.cob: Likewise. + * cobol.dg/group2/INSPECT_BACKWARD_simple_REPLACING.cob: Likewise. + * cobol.dg/group2/INSPECT_BACKWARD_simple_TALLYING.cob: Likewise. + * cobol.dg/group2/INSPECT_CONVERTING_NULL.cob: Likewise. + * cobol.dg/group2/INSPECT_CONVERTING_TO_figurative_constant.cob: Likewise. + * cobol.dg/group2/INSPECT_CONVERTING_TO_figurative_constants.cob: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_1.cob: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_2.cob: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_3.cob: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_4.cob: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_5.cob: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_5-f.cob: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_5-r.cob: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_6.cob: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_7.cob: Likewise. + * cobol.dg/group2/INSPECT_No_repeat_conversion_check.cob: Likewise. + * cobol.dg/group2/INSPECT_REPLACING_figurative_constant.cob: Likewise. + * cobol.dg/group2/INSPECT_REPLACING_LEADING_ZEROS_BY_SPACES.cob: Likewise. + * cobol.dg/group2/INSPECT_TALLYING_AFTER.cob: Likewise. + * cobol.dg/group2/INSPECT_TALLYING_BEFORE.cob: Likewise. + * cobol.dg/group2/INSPECT_TALLYING_REPLACING_ISO_Example.cob: Likewise. + * cobol.dg/group2/INSPECT_TRAILING.cob: Likewise. + * cobol.dg/group2/INSPECT_BACKWARD_REPLACING_LEADING.out: New known-good result. + * cobol.dg/group2/INSPECT_BACKWARD_REPLACING_TRAILING.out: Likewise. + * cobol.dg/group2/INSPECT_BACKWARD_simple_CONVERTING.out: Likewise. + * cobol.dg/group2/INSPECT_BACKWARD_simple_REPLACING.out: Likewise. + * cobol.dg/group2/INSPECT_BACKWARD_simple_TALLYING.out: Likewise. + * cobol.dg/group2/INSPECT_CONVERTING_TO_figurative_constants.out: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_1.out: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_2.out: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_3.out: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_4.out: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_5-f.out: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_5.out: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_5-r.out: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_6.out: Likewise. + * cobol.dg/group2/INSPECT_ISO_Example_7.out: Likewise. + * cobol.dg/group2/INSPECT_TALLYING_REPLACING_ISO_Example.out: Likewise. + * cobol.dg/group2/INSPECT_TRAILING.out: Likewise. + +2025-04-03 Andrew Pinski <quic_apinski@quicinc.com> + Jakub Jelinek <jakub@redhat.com> + + PR c++/119563 + * g++.dg/cpp0x/pr119563.C: New test. + * g++.dg/cpp/embed-26.C: New test. + +2025-04-03 Christophe Lyon <christophe.lyon@linaro.org> + + * gcc.dg/guality/pr90074.c: Remove xfail for aarch64. + * gcc.dg/guality/pr90716.c: Likewise. + +2025-04-03 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * gcc.target/i386/pr111673.c (dg-options): Add + -fasynchronous-unwind-tables -fdwarf2-cfi-asm. + * gcc.target/i386/pr82142a.c: Likewise. + * gcc.target/i386/pr82142b.c (dg-options): Add -mno-stackrealign + -fasynchronous-unwind-tables -fdwarf2-cfi-asm. + +2025-04-03 Alexandre Oliva <oliva@adacore.com> + + * gcc.target/riscv/rvv/base/vwaddsub-1.c: Require rv64. + +2025-04-03 Alexandre Oliva <oliva@adacore.com> + + * gcc.target/riscv/mcpu-xiangshan-nanhu.c: Skip on non-rv64. + +2025-04-03 Alexandre Oliva <oliva@adacore.com> + + PR tree-optimization/113281 + * gcc.dg/vect/costmodel/riscv/rvv/pr113281-1.c: XFAIL. + * gcc.dg/vect/costmodel/riscv/rvv/pr113281-2.c: Likewise. + * gcc.dg/vect/costmodel/riscv/rvv/pr113281-5.c: Likewise. + +2025-04-03 Alexandre Oliva <oliva@adacore.com> + + * gcc.dg/tree-ssa/ssa-dom-cse-2.c: XFAIL on riscv lp64. + +2025-04-03 Hongyu Wang <hongyu.wang@intel.com> + + PR target/119539 + * gcc.target/i386/apx-nf-pr119539.c: New test. + 2025-04-02 Jin Ma <jinma@linux.alibaba.com> * gcc.target/riscv/zba-shNadd-09.c: New test. diff --git a/gcc/testsuite/c-c++-common/pr119614-1.c b/gcc/testsuite/c-c++-common/pr119614-1.c new file mode 100644 index 0000000..89105a3 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr119614-1.c @@ -0,0 +1,28 @@ +/* PR tree-optimization/119614 */ +/* { dg-do compile { target musttail } } */ +/* { dg-options "-O2" } */ + +volatile int v; + +[[gnu::noinline]] const char * +foo (int x) +{ + v += x; + return 0; +} + +const char * +bar (int x) +{ + if (x == 42) + [[gnu::musttail]] return foo (42); + [[gnu::musttail]] return foo (32); +} + +const char * +baz (int x) +{ + if (x == 5) + return foo (42); + return foo (32); +} diff --git a/gcc/testsuite/c-c++-common/pr119614-2.c b/gcc/testsuite/c-c++-common/pr119614-2.c new file mode 100644 index 0000000..8833eee --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr119614-2.c @@ -0,0 +1,28 @@ +/* PR tree-optimization/119614 */ +/* { dg-do compile { target musttail } } */ +/* { dg-options "-O2" } */ + +volatile int v; + +[[gnu::noinline]] const char * +foo (int x) +{ + v += x; + return (const char *) -42; +} + +const char * +bar (int x) +{ + if (x == 42) + [[gnu::musttail]] return foo (42); + [[gnu::musttail]] return foo (32); +} + +const char * +baz (int x) +{ + if (x == 5) + return foo (42); + return foo (32); +} diff --git a/gcc/testsuite/c-c++-common/pr119614-3.c b/gcc/testsuite/c-c++-common/pr119614-3.c new file mode 100644 index 0000000..59ed36b --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr119614-3.c @@ -0,0 +1,28 @@ +/* PR tree-optimization/119614 */ +/* { dg-do compile { target musttail } } */ +/* { dg-options "-O2" } */ + +volatile int v; + +[[gnu::noinline]] double +foo (int x) +{ + v += x; + return 0.5; +} + +double +bar (int x) +{ + if (x == 42) + [[gnu::musttail]] return foo (42); + [[gnu::musttail]] return foo (32); +} + +double +baz (int x) +{ + if (x == 5) + return foo (42); + return foo (32); +} diff --git a/gcc/testsuite/c-c++-common/pr119616.c b/gcc/testsuite/c-c++-common/pr119616.c new file mode 100644 index 0000000..5ffdb8c --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr119616.c @@ -0,0 +1,23 @@ +/* PR tree-optimization/119616 */ +/* { dg-do compile { target external_musttail } } */ +/* { dg-options "-O2" } */ + +int foo (int *); +int bar (int); + +int +baz (int x) +{ + if (!x) + [[gnu::musttail]] return bar (x); + return foo (&x); +} + +int +qux (int x) +{ + if (!x) + [[gnu::musttail]] return bar (x); + foo (&x); + return 1; +} diff --git a/gcc/testsuite/c-c++-common/pr119618.c b/gcc/testsuite/c-c++-common/pr119618.c new file mode 100644 index 0000000..a56e669 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr119618.c @@ -0,0 +1,21 @@ +/* PR gcov-profile/119618 */ +/* { dg-do compile { target musttail } } */ +/* { dg-options "-fcompare-debug -fprofile-generate -O1" } */ +/* { dg-require-profiling "-fprofile-generate" } */ + +struct S { char s; }; +int foo (void); +int *(*fn) (void); + +int * +bar (void) +{ + if (foo ()) + return 0; + { + struct S s; + do + [[gnu::musttail]] return fn (); + while (0); + } +} diff --git a/gcc/testsuite/g++.dg/cpp/pr119391.C b/gcc/testsuite/g++.dg/cpp/pr119391.C new file mode 100644 index 0000000..6e70efc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp/pr119391.C @@ -0,0 +1,15 @@ +// PR preprocessor/119391 +// { dg-do preprocess } +// { dg-options "" } + +#if (1 << 63) != -9223372036854775807 - 1 // { dg-warning "integer overflow in preprocessor expression" "" { target c++98_only } } +#warning "Unexpected value" +#endif +#if (3 << 62) != -4611686018427387904 // { dg-warning "integer overflow in preprocessor expression" "" { target c++98_only } } +#warning "Unexpected value" +#endif +#if 1 << 64 // { dg-warning "integer overflow in preprocessor expression" } +#endif +#if (3 << 63) != -9223372036854775807 - 1 // { dg-warning "integer overflow in preprocessor expression" "" { target c++17_down } } +#warning "Unexpected value" +#endif diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires41.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires41.C new file mode 100644 index 0000000..28c9761 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires41.C @@ -0,0 +1,25 @@ +// PR c++/117849 +// { dg-do compile { target c++20 } } + +template<int N> +struct array { + constexpr int size() const { return N; } +}; + +struct vector { + int _size = 3; + constexpr int size() const { return _size; } +}; + +template<int N> +struct integral_constant { + constexpr operator int() const { return N; } +}; + +template<class T> +concept StaticSize = requires (T& t) { + typename integral_constant<t.size()>; +}; + +static_assert(StaticSize<array<5>>); +static_assert(!StaticSize<vector>); diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-requires2.C b/gcc/testsuite/g++.dg/cpp2a/lambda-requires2.C new file mode 100644 index 0000000..be5a71a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-requires2.C @@ -0,0 +1,8 @@ +// PR c++/99546 +// { dg-do compile { target c++20 } } + +int main() { + constexpr auto b = requires { []{}; }; + static_assert(b); + static_assert(!b); // { dg-error "assertion failed" } +} diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-requires3.C b/gcc/testsuite/g++.dg/cpp2a/lambda-requires3.C new file mode 100644 index 0000000..8c4ef06 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-requires3.C @@ -0,0 +1,6 @@ +// PR c++/113925 +// { dg-do compile { target c++20 } } + +template<bool B> +struct b{}; +static_assert(requires { b<([]()consteval{ return true; }())>{}; }); diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-requires4.C b/gcc/testsuite/g++.dg/cpp2a/lambda-requires4.C new file mode 100644 index 0000000..f3bb041 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-requires4.C @@ -0,0 +1,6 @@ +// PR c++/106976 +// { dg-do compile { target c++20 } } + +struct S{ + constexpr static auto s = requires { []; }; // { dg-error "expected '\{'" } +}; diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-requires5.C b/gcc/testsuite/g++.dg/cpp2a/lambda-requires5.C new file mode 100644 index 0000000..c818313 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-requires5.C @@ -0,0 +1,10 @@ +// PR c++/109961 +// { dg-do compile { target c++20 } } + +auto a = requires{ + []( int b ) consteval { + if( b ) { + throw b; + } + }( 0 ); +}; diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite6.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite6.C new file mode 100644 index 0000000..0ec74e8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-rewrite6.C @@ -0,0 +1,33 @@ +// { dg-do compile { target c++20 } } + +// We wrongly considered D to be ne_comparable because we were looking for a +// corresponding op!= for N::op== in ::, because ::op== happened to be the +// first thing in the lookup set. + +template<bool, typename _Tp = void> +struct enable_if; + +template<typename _Tp> +struct enable_if<true, _Tp> +{ typedef _Tp type; }; + +template <class T, class U> struct A { }; + +namespace N { + struct X { }; + template <class T> auto operator== (const A<T,X>&, const A<T,X>&) + -> typename enable_if<sizeof(T() == T()), bool>::type; + template <class T> auto operator!= (const A<T,X>&, const A<T,X>&) + -> typename enable_if<sizeof(T() != T()), bool>::type; +} + +template<typename T, typename U = T> +concept ne_comparable += requires (const A<T,N::X>& t, const A<U,N::X>& u) { + t != u; +}; + +struct D { }; +int operator==(D, D); +bool operator!=(D, D) = delete; +static_assert( ! ne_comparable<D> ); diff --git a/gcc/testsuite/g++.dg/opt/pr119613.C b/gcc/testsuite/g++.dg/opt/pr119613.C new file mode 100644 index 0000000..432a30c --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr119613.C @@ -0,0 +1,22 @@ +// PR middle-end/119613 +// { dg-do compile { target { musttail && { c || c++11 } } } } +// { dg-options "-O0" } + +struct S { S () {} }; +char *foo (S); +void bar (int); + +[[gnu::always_inline]] inline char * +baz (S x) +{ + unsigned i; + &i; + bar (i); + [[gnu::musttail]] return foo (x); +} + +char * +qux (S) +{ + [[gnu::musttail]] return baz (S {}); +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr46534.c b/gcc/testsuite/gcc.c-torture/compile/pr46534.c index 1894636..7f10bc0 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr46534.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr46534.c @@ -1,4 +1,3 @@ -/* { dg-skip-if "too big" { nvptx-*-* } } */ /* PR middle-end/46534 */ extern int printf (const char *, ...); diff --git a/gcc/testsuite/gcc.dg/builtin-apply5.c b/gcc/testsuite/gcc.dg/builtin-apply5.c new file mode 100644 index 0000000..16892f7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-apply5.c @@ -0,0 +1,23 @@ +/* { dg-options "-O2 -Wmissing-noreturn -fgnu89-inline" } */ +/* { dg-additional-options "-mno-mmx" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */ +/* { dg-do compile } */ + +extern void abort (void); + +double +foo (int arg) +{ + if (arg != 116) + abort(); + return arg + 1; +} + +__attribute__((noreturn)) +double +bar (int arg) +{ + foo (arg); + __builtin_return (__builtin_apply ((void (*) ()) foo, /* { dg-warning "'noreturn' function does return" } */ + __builtin_apply_args (), 16)); +} + diff --git a/gcc/testsuite/gcc.dg/torture/pr119599-1.c b/gcc/testsuite/gcc.dg/torture/pr119599-1.c new file mode 100644 index 0000000..4fbd228 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr119599-1.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-einline" } */ + +/* PR ipa/119599 */ +/* inlining a noreturn function which returns + can cause an ICE when dealing finding an unreachable block. + We should get a __builtin_unreachable after the inliing. */ + + +void baz (void); + +static inline __attribute__((always_inline, noreturn)) void +bar (void) +{ + static volatile int t = 0; + if (t == 0) + baz (); +} /* { dg-warning "function does return" } */ + +void +foo (void) +{ + bar (); +} + +/* After inlining, we should have call to __builtin_unreachable now. */ +/* { dg-final { scan-tree-dump "__builtin_unreachable " "einline" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-fncall-mask.c b/gcc/testsuite/gcc.dg/vect/vect-fncall-mask.c index 554488e..ba1886d 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-fncall-mask.c +++ b/gcc/testsuite/gcc.dg/vect/vect-fncall-mask.c @@ -1,7 +1,7 @@ /* { dg-do compile { target { aarch64*-*-* } } } */ -/* { dg-additional-options "-march=armv8.2-a+sve -fdump-tree-ifcvt-raw -Ofast" { target { aarch64*-*-* } } } */ +/* { dg-additional-options "-march=armv8.2-a+sve -fdump-tree-ifcvt -Ofast" { target { aarch64*-*-* } } } */ -extern int __attribute__ ((simd, const)) fn (int); +extern int __attribute__ ((simd, const)) fn (float); const int N = 20; const float lim = 101.0; @@ -26,6 +26,4 @@ int main (void) return (0); } -/* { dg-final { scan-tree-dump {gimple_assign <gt_expr, _12, _1, 1.01e\+2, NULL>} ifcvt } } */ -/* { dg-final { scan-tree-dump {gimple_assign <bit_not_expr, _34, _12, NULL, NULL>} ifcvt } } */ -/* { dg-final { scan-tree-dump {gimple_call <.MASK_CALL, _3, fn, _2, _34>} ifcvt } } */ +/* { dg-final { scan-tree-dump {(_\d+) = (_\d+) > 1.01e\+2;\n\s*(_\d+) = ~\1;\n\s*_\d+ = .MASK_CALL \(fn, \2, \3\);} ifcvt } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/mve.exp b/gcc/testsuite/gcc.target/arm/mve/mve.exp index a5d8511..9dc56c9 100644 --- a/gcc/testsuite/gcc.target/arm/mve/mve.exp +++ b/gcc/testsuite/gcc.target/arm/mve/mve.exp @@ -35,6 +35,7 @@ global dg_runtest_extra_prunes set dg_runtest_extra_prunes "" lappend dg_runtest_extra_prunes "warning: switch '-m(cpu|arch)=.*' conflicts with switch '-m(cpu|arch)=.*'" +set saved-dg-do-what-default ${dg-do-what-default} set dg-do-what-default "assemble" # Initialize `dg'. @@ -53,6 +54,8 @@ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/general-c/*.\[cCS\]]] \ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \ "" $DEFAULT_CFLAGS +set dg-do-what-default ${saved-dg-do-what-default} + # All done. set dg_runtest_extra_prunes "" dg-finish diff --git a/gcc/testsuite/gcc.target/i386/pr115910.c b/gcc/testsuite/gcc.target/i386/pr115910.c new file mode 100644 index 0000000..5f1cd9a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr115910.c @@ -0,0 +1,20 @@ +/* PR target/115910 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -march=x86-64 -mtune=generic -masm=att" } */ +/* { dg-final { scan-assembler-times {\timulq\t} 2 } } */ +/* { dg-final { scan-assembler-times {\tshrq\t\$33,} 2 } } */ +/* { dg-final { scan-assembler-not {\tsarl\t} } } */ + +int +foo (int x) +{ + if (x < 0) + __builtin_unreachable (); + return x / 3U; +} + +int +bar (int x) +{ + return x / 3U; +} diff --git a/gcc/testsuite/gcc.target/nvptx/decl.c b/gcc/testsuite/gcc.target/nvptx/decl.c index 190a64d..45dd699 100644 --- a/gcc/testsuite/gcc.target/nvptx/decl.c +++ b/gcc/testsuite/gcc.target/nvptx/decl.c @@ -13,8 +13,8 @@ int Foo () } /* { dg-final { scan-assembler "\[\r\n\]\[\t \]*.visible .global \[^,\r\n\]*glob_export" } } */ -/* { dg-final { scan-assembler "\[\r\n\]\[\t \]*.visible .const \[^,\r\n\]*cst_export" } } */ +/* { dg-final { scan-assembler "\[\r\n\]\[\t \]*.visible .global \[^,\r\n\]*cst_export" } } */ /* { dg-final { scan-assembler "\[\r\n\]\[\t \]*.global \[^,\r\n\]*glob_local" } } */ -/* { dg-final { scan-assembler "\[\r\n\]\[\t \]*.const \[^,\r\n\]*cst_local" } } */ +/* { dg-final { scan-assembler "\[\r\n\]\[\t \]*.global \[^,\r\n\]*cst_local" } } */ /* { dg-final { scan-assembler "\[\r\n\]\[\t \]*.extern .global \[^,\r\n\]*glob_import" } } */ -/* { dg-final { scan-assembler "\[\r\n\]\[\t \]*.extern .const \[^,\r\n\]*cst_import" } } */ +/* { dg-final { scan-assembler "\[\r\n\]\[\t \]*.extern .global \[^,\r\n\]*cst_import" } } */ diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 2fa5678..ecf19d2 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -9799,18 +9799,20 @@ pass_warn_function_return::execute (function *fun) (e = ei_safe_edge (ei)); ) { last = *gsi_last_bb (e->src); - if ((gimple_code (last) == GIMPLE_RETURN - || gimple_call_builtin_p (last, BUILT_IN_RETURN)) - && location == UNKNOWN_LOCATION - && ((location = LOCATION_LOCUS (gimple_location (last))) - != UNKNOWN_LOCATION) - && !optimize) - break; - /* When optimizing, replace return stmts in noreturn functions + /* Warn about __builtin_return .*/ + if (gimple_call_builtin_p (last, BUILT_IN_RETURN) + && location == UNKNOWN_LOCATION) + { + location = LOCATION_LOCUS (gimple_location (last)); + ei_next (&ei); + } + /* Replace return stmts in noreturn functions with __builtin_unreachable () call. */ - if (optimize && gimple_code (last) == GIMPLE_RETURN) + else if (gimple_code (last) == GIMPLE_RETURN) { location_t loc = gimple_location (last); + if (location == UNKNOWN_LOCATION) + location = LOCATION_LOCUS (loc); gimple *new_stmt = gimple_build_builtin_unreachable (loc); gimple_stmt_iterator gsi = gsi_for_stmt (last); gsi_replace (&gsi, new_stmt, true); diff --git a/gcc/tree-tailcall.cc b/gcc/tree-tailcall.cc index 477729c..c8740f9 100644 --- a/gcc/tree-tailcall.cc +++ b/gcc/tree-tailcall.cc @@ -165,8 +165,6 @@ suitable_for_tail_opt_p (gcall *call, bool diag_musttail) static bool suitable_for_tail_call_opt_p (gcall *call, bool diag_musttail) { - tree param; - /* alloca (until we have stack slot life analysis) inhibits sibling call optimizations, but not tail recursion. */ if (cfun->calls_alloca) @@ -204,18 +202,6 @@ suitable_for_tail_call_opt_p (gcall *call, bool diag_musttail) return false; } - /* ??? It is OK if the argument of a function is taken in some cases, - but not in all cases. See PR15387 and PR19616. Revisit for 4.1. */ - if (!diag_musttail || !gimple_call_must_tail_p (call)) - for (param = DECL_ARGUMENTS (current_function_decl); - param; param = DECL_CHAIN (param)) - if (TREE_ADDRESSABLE (param)) - { - maybe_error_musttail (call, _("address of caller arguments taken"), - diag_musttail); - return false; - } - if (diag_musttail && gimple_call_must_tail_p (call) && warn_musttail_local_addr) @@ -565,6 +551,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail, basic_block abb; size_t idx; tree var; + bool only_tailr = false; if (!single_succ_p (bb) && (EDGE_COUNT (bb->succs) || !cfun->has_musttail || !diag_musttail)) @@ -660,6 +647,25 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail, if (!suitable_for_tail_call_opt_p (call, diag_musttail)) opt_tailcalls = false; + /* ??? It is OK if the argument of a function is taken in some cases, + but not in all cases. See PR15387 and PR19616. Revisit for 4.1. */ + if (!diag_musttail || !gimple_call_must_tail_p (call)) + for (param = DECL_ARGUMENTS (current_function_decl); + param; param = DECL_CHAIN (param)) + if (TREE_ADDRESSABLE (param)) + { + maybe_error_musttail (call, _("address of caller arguments taken"), + diag_musttail); + /* If current function has musttail calls, we can't disable tail + calls altogether for the whole caller, because those might be + actually fine. So just punt if this exact call is not + a tail recursion. */ + if (cfun->has_musttail) + only_tailr = true; + else + opt_tailcalls = false; + } + /* If the LHS of our call is not just a simple register or local variable, we can't transform this into a tail or sibling call. This situation happens, in (e.g.) "*p = foo()" where foo returns a @@ -794,6 +800,9 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail, tail_recursion = true; } + if (only_tailr && !tail_recursion) + return; + /* Compute live vars if not computed yet. */ if (live_vars == NULL) { @@ -1036,7 +1045,9 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail, && TREE_CONSTANT (ret_var)) if (tree type = gimple_range_type (call)) if (tree callee = gimple_call_fndecl (call)) - if ((INTEGRAL_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type)) + if ((INTEGRAL_TYPE_P (type) + || SCALAR_FLOAT_TYPE_P (type) + || POINTER_TYPE_P (type)) && useless_type_conversion_p (TREE_TYPE (TREE_TYPE (callee)), type) && useless_type_conversion_p (TREE_TYPE (ret_var), type) |