From 78ee8381bf0ebd09a92936bdb9e1b5c9fc85ad88 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 28 Dec 2021 17:39:23 +0100 Subject: optabs: Fix up checking for CALLs in newly added code by double-word divmod [PR103838] These two spots are meant to punt if the newly added code contains any CALL_INSNs, because in that case having a large sequence of insns that also calls something is undesirable, better have one call that is optimized in itself well. The functions do last = get_last_insn (); before emitting any insns (and expand_binop as the ultimate caller uses delete_insns_since if the expansion fails), but the checks were incorrect for 2 reasons: 1) it checked not just what follows after that last insn, but also the last insn itself; so, if the division or modulo is immediately preceded by a CALL_INSN, then we punt; this also causes -fcompare-debug failures if the CALL_INSN is with -g followed by one or more DEBUG_INSNs 2) if get_last_insn () is NULL (i.e. emitting into a new sequence), then we didn't check anything 2021-12-28 Jakub Jelinek PR debug/103838 * optabs.c (expand_doubleword_mod, expand_doubleword_divmod): Only check newly added insns for CALL_P, not the last insn of previous code. * gcc.dg/pr103838.c: New test. --- gcc/optabs.c | 8 ++++++++ gcc/testsuite/gcc.dg/pr103838.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr103838.c (limited to 'gcc') diff --git a/gcc/optabs.c b/gcc/optabs.c index 019bbb6..ca00bbd 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -1135,6 +1135,10 @@ expand_doubleword_mod (machine_mode mode, rtx op0, rtx op1, bool unsignedp) remainder = convert_modes (mode, word_mode, remainder, unsignedp); /* Punt if we need any library calls. */ + if (last) + last = NEXT_INSN (last); + else + last = get_insns (); for (; last; last = NEXT_INSN (last)) if (CALL_P (last)) return NULL_RTX; @@ -1228,6 +1232,10 @@ expand_doubleword_divmod (machine_mode mode, rtx op0, rtx op1, rtx *rem, } /* Punt if we need any library calls. */ + if (last) + last = NEXT_INSN (last); + else + last = get_insns (); for (; last; last = NEXT_INSN (last)) if (CALL_P (last)) return NULL_RTX; diff --git a/gcc/testsuite/gcc.dg/pr103838.c b/gcc/testsuite/gcc.dg/pr103838.c new file mode 100644 index 0000000..cde44e6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr103838.c @@ -0,0 +1,28 @@ +/* PR debug/103838 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fcompare-debug" } */ + +#ifdef __SIZEOF_INT128__ +__int128 m; +#else +long long m; +#endif +int n; + +__attribute__((noinline)) void +bar (void) +{ + n += !!m; +} + +void +foo (void) +{ + int i; + + for (i = 0; i < 2; ++i) + { + bar (); + m /= 3; + } +} -- cgit v1.1 From 3c5fd3616f73fbcd241cc3a5e09275c2b0c49bd4 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 28 Dec 2021 17:40:17 +0100 Subject: loop-invariant: Fix -fcompare-debug failure [PR103837] In the following testcase we have a -fcompare-debug failure, because can_move_invariant_reg doesn't ignore DEBUG_INSNs in its decisions. In the testcase we have due to uninitialized variable: loop_header debug_insn using pseudo84 pseudo84 = invariant insn using pseudo84 end loop and with -g decide not to move the pseudo84 = invariant before the loop header; in this case not resetting the debug insns might be fine. But, we could have also: pseudo84 = whatever loop_header debug_insn using pseudo84 pseudo84 = invariant insn using pseudo84 end loop and in that case not resetting the debug insns would result in wrong-debug. And, we don't really have generally a good substitution on what pseudo84 contains, it could inherit various values from different paths. So, the following patch ignores DEBUG_INSNs in the decisions, and if there are any that previously prevented the optimization, resets them before return true. 2021-12-28 Jakub Jelinek PR rtl-optimization/103837 * loop-invariant.c (can_move_invariant_reg): Ignore DEBUG_INSNs in the decisions whether to return false or continue and right before returning true reset those debug insns that previously caused returning false. * gcc.dg/pr103837.c: New test. --- gcc/loop-invariant.c | 19 +++++++++++++++---- gcc/testsuite/gcc.dg/pr103837.c | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr103837.c (limited to 'gcc') diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index 5eee2e5..be95155 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -1691,6 +1691,7 @@ can_move_invariant_reg (class loop *loop, struct invariant *inv, rtx reg) unsigned int dest_regno, defs_in_loop_count = 0; rtx_insn *insn = inv->insn; basic_block bb = BLOCK_FOR_INSN (inv->insn); + auto_vec debug_insns_to_reset; /* We ignore hard register and memory access for cost and complexity reasons. Hard register are few at this stage and expensive to consider as they @@ -1725,10 +1726,13 @@ can_move_invariant_reg (class loop *loop, struct invariant *inv, rtx reg) continue; /* Don't move if a use is not dominated by def in insn. */ - if (use_bb == bb && DF_INSN_LUID (insn) >= DF_INSN_LUID (use_insn)) - return false; - if (!dominated_by_p (CDI_DOMINATORS, use_bb, bb)) - return false; + if ((use_bb == bb && DF_INSN_LUID (insn) >= DF_INSN_LUID (use_insn)) + || !dominated_by_p (CDI_DOMINATORS, use_bb, bb)) + { + if (!DEBUG_INSN_P (use_insn)) + return false; + debug_insns_to_reset.safe_push (use_insn); + } } /* Check for other defs. Any other def in the loop might reach a use @@ -1751,6 +1755,13 @@ can_move_invariant_reg (class loop *loop, struct invariant *inv, rtx reg) return false; } + /* Reset debug uses if a use is not dominated by def in insn. */ + for (auto use_insn : debug_insns_to_reset) + { + INSN_VAR_LOCATION_LOC (use_insn) = gen_rtx_UNKNOWN_VAR_LOC (); + df_insn_rescan (use_insn); + } + return true; } diff --git a/gcc/testsuite/gcc.dg/pr103837.c b/gcc/testsuite/gcc.dg/pr103837.c new file mode 100644 index 0000000..43593d5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr103837.c @@ -0,0 +1,19 @@ +/* PR rtl-optimization/103837 */ +/* { dg-do compile } */ +/* { dg-options "-Og -fcompare-debug -fmove-loop-invariants -fnon-call-exceptions -fexceptions -fdelete-dead-exceptions -fno-tree-dce -w" } */ + +unsigned long int +foo (int x) +{ + double a; + int b; + unsigned long int ret = a; + + for (;;) + { + b = !!((int) a); + a = x; + } + + return ret; +} -- cgit v1.1 From 9258ac53cfcbe546e8b86a433e59343538743f74 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 28 Dec 2021 17:41:24 +0100 Subject: fold-const: Fix up fold_truth_andor_1 shift handling [PR103813] Some time ago I've changed const_binop -> wide_int_binop, so that it punts on shifts by negative count. fold_truth_andor_1 doesn't check the results of const_binop (?SHIFT_EXPR, ) though and assumes they will be always non-NULL, which is no longer the case. 2021-12-28 Jakub Jelinek PR middle-end/103813 * fold-const.c (fold_truth_andor_1): Punt of const_binop LSHIFT_EXPR or RSHIFT_EXPR returns NULL. Formatting fix. * gcc.c-torture/compile/pr103813.c: New test. --- gcc/fold-const.c | 14 ++++++++++++-- gcc/testsuite/gcc.c-torture/compile/pr103813.c | 10 ++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr103813.c (limited to 'gcc') diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0b9a42f..14aa9ca 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -6454,15 +6454,19 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type, size_int (xll_bitpos)); rl_mask = const_binop (LSHIFT_EXPR, fold_convert_loc (loc, lntype, rl_mask), size_int (xrl_bitpos)); + if (ll_mask == NULL_TREE || rl_mask == NULL_TREE) + return 0; if (l_const) { l_const = fold_convert_loc (loc, lntype, l_const); l_const = unextend (l_const, ll_bitsize, ll_unsignedp, ll_and_mask); l_const = const_binop (LSHIFT_EXPR, l_const, size_int (xll_bitpos)); + if (l_const == NULL_TREE) + return 0; if (! integer_zerop (const_binop (BIT_AND_EXPR, l_const, fold_build1_loc (loc, BIT_NOT_EXPR, - lntype, ll_mask)))) + lntype, ll_mask)))) { warning (0, "comparison is always %d", wanted_code == NE_EXPR); @@ -6474,9 +6478,11 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type, r_const = fold_convert_loc (loc, lntype, r_const); r_const = unextend (r_const, rl_bitsize, rl_unsignedp, rl_and_mask); r_const = const_binop (LSHIFT_EXPR, r_const, size_int (xrl_bitpos)); + if (r_const == NULL_TREE) + return 0; if (! integer_zerop (const_binop (BIT_AND_EXPR, r_const, fold_build1_loc (loc, BIT_NOT_EXPR, - lntype, rl_mask)))) + lntype, rl_mask)))) { warning (0, "comparison is always %d", wanted_code == NE_EXPR); @@ -6521,6 +6527,8 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type, rr_mask = const_binop (LSHIFT_EXPR, fold_convert_loc (loc, rntype, rr_mask), size_int (xrr_bitpos)); + if (lr_mask == NULL_TREE || rr_mask == NULL_TREE) + return 0; /* Make a mask that corresponds to both fields being compared. Do this for both items being compared. If the operands are the @@ -6580,6 +6588,8 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type, size_int (MIN (xll_bitpos, xrl_bitpos))); lr_mask = const_binop (RSHIFT_EXPR, lr_mask, size_int (MIN (xlr_bitpos, xrr_bitpos))); + if (ll_mask == NULL_TREE || lr_mask == NULL_TREE) + return 0; /* Convert to the smaller type before masking out unwanted bits. */ type = lntype; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr103813.c b/gcc/testsuite/gcc.c-torture/compile/pr103813.c new file mode 100644 index 0000000..b3fc066 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr103813.c @@ -0,0 +1,10 @@ +/* PR middle-end/103813 */ + +struct A { char b; char c[0x21000000]; }; +struct A d; + +int +foo () +{ + return d.c[0x20000000] || d.c[1]; +} -- cgit v1.1 From db25655fa5dd23bba684ec7db628643c19e64d6a Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 27 Dec 2021 23:46:13 -0500 Subject: c++: ICE on enum with bool value [PR99968] BOOLEAN_TYPE also counts as integral, so verify_type should allow it. PR c++/99968 gcc/ChangeLog: * tree.c (verify_type): Allow enumerator with BOOLEAN_TYPE. gcc/testsuite/ChangeLog: * g++.dg/ext/is_enum2.C: New test. --- gcc/testsuite/g++.dg/ext/is_enum2.C | 10 ++++++++++ gcc/tree.c | 1 + 2 files changed, 11 insertions(+) create mode 100644 gcc/testsuite/g++.dg/ext/is_enum2.C (limited to 'gcc') diff --git a/gcc/testsuite/g++.dg/ext/is_enum2.C b/gcc/testsuite/g++.dg/ext/is_enum2.C new file mode 100644 index 0000000..de14d6a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_enum2.C @@ -0,0 +1,10 @@ +// PR c++/99968 +// { dg-do compile { target c++11 } } +// { dg-additional-options -g } + +template struct A { + using type = T; + static const bool value = false; +}; + +enum E { e0 = __is_enum(E), e1 = A::value }; diff --git a/gcc/tree.c b/gcc/tree.c index 0741e3b..d68d694 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -13704,6 +13704,7 @@ verify_type (const_tree t) error_found = true; } if (TREE_CODE (TREE_TYPE (value)) != INTEGER_TYPE + && TREE_CODE (TREE_TYPE (value)) != BOOLEAN_TYPE && !useless_type_conversion_p (const_cast (t), TREE_TYPE (value))) { error ("enum value type is not % nor convertible " -- cgit v1.1 From 906b4e15ce84790c7657405238d61358e0893676 Mon Sep 17 00:00:00 2001 From: Francois-Xavier Coudert Date: Sun, 26 Dec 2021 20:18:01 +0100 Subject: Fortran: Emit correct types for CHARACTER(C_CHAR), VALUE arguments Make the front-end emit the right type for CHARACTER(C_CHAR), VALUE arguments to BIND(C) procedures. They are scalar integers of C type char, and should be emitted as such. They are not strings or arrays, and are not promoted to C int, either. gcc/fortran/ChangeLog: PR fortran/103828 * trans-decl.c (generate_local_decl): Do not call gfc_conv_scalar_char_value(), but check the type tree. * trans-expr.c (gfc_conv_scalar_char_value): Rename to conv_scalar_char_value, do not alter type tree. (gfc_conv_procedure_call): Adjust call to renamed conv_scalar_char_value() function. * trans-types.c (gfc_sym_type): Take care of CHARACTER(C_CHAR), VALUE arguments. * trans.h (gfc_conv_scalar_char_value): Remove prototype. gcc/testsuite/ChangeLog: PR fortran/103828 * gfortran.dg/c_char_tests_3.f90: New file. * gfortran.dg/c_char_tests_3_c.c: New file. * gfortran.dg/c_char_tests_4.f90: New file. * gfortran.dg/c_char_tests_5.f90: New file. --- gcc/fortran/trans-decl.c | 17 ++++-- gcc/fortran/trans-expr.c | 86 ++++++++++++-------------- gcc/fortran/trans-types.c | 2 +- gcc/fortran/trans.h | 1 - gcc/testsuite/gfortran.dg/c_char_tests_3.f90 | 51 ++++++++++++++++ gcc/testsuite/gfortran.dg/c_char_tests_3_c.c | 16 +++++ gcc/testsuite/gfortran.dg/c_char_tests_4.f90 | 90 ++++++++++++++++++++++++++++ gcc/testsuite/gfortran.dg/c_char_tests_5.f90 | 49 +++++++++++++++ 8 files changed, 255 insertions(+), 57 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/c_char_tests_3.f90 create mode 100644 gcc/testsuite/gfortran.dg/c_char_tests_3_c.c create mode 100644 gcc/testsuite/gfortran.dg/c_char_tests_4.f90 create mode 100644 gcc/testsuite/gfortran.dg/c_char_tests_5.f90 (limited to 'gcc') diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index cb7f684..d288af5 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -6001,15 +6001,20 @@ generate_local_decl (gfc_symbol * sym) if (sym->attr.dummy == 1) { - /* Modify the tree type for scalar character dummy arguments of bind(c) - procedures if they are passed by value. The tree type for them will - be promoted to INTEGER_TYPE for the middle end, which appears to be - what C would do with characters passed by-value. The value attribute - implies the dummy is a scalar. */ + /* The tree type for scalar character dummy arguments of BIND(C) + procedures, if they are passed by value, should be unsigned char. + The value attribute implies the dummy is a scalar. */ if (sym->attr.value == 1 && sym->backend_decl != NULL && sym->ts.type == BT_CHARACTER && sym->ts.is_c_interop && sym->ns->proc_name != NULL && sym->ns->proc_name->attr.is_bind_c) - gfc_conv_scalar_char_value (sym, NULL, NULL); + { + /* We used to modify the tree here. Now it is done earlier in + the front-end, so we only check it here to avoid regressions. */ + gcc_assert (TREE_CODE (TREE_TYPE (sym->backend_decl)) == INTEGER_TYPE); + gcc_assert (TYPE_UNSIGNED (TREE_TYPE (sym->backend_decl)) == 1); + gcc_assert (TYPE_PRECISION (TREE_TYPE (sym->backend_decl)) == CHAR_TYPE_SIZE); + gcc_assert (DECL_BY_REFERENCE (sym->backend_decl) == 0); + } /* Unused procedure passed as dummy argument. */ if (sym->attr.flavor == FL_PROCEDURE) diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index e413b2d..80c669f 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "trans-stmt.h" #include "dependency.h" #include "gimplify.h" +#include "tm.h" /* For CHAR_TYPE_SIZE. */ /* Calculate the number of characters in a string. */ @@ -3972,63 +3973,50 @@ gfc_string_to_single_character (tree len, tree str, int kind) } -void -gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr) +static void +conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr) { + gcc_assert (expr); + /* We used to modify the tree here. Now it is done earlier in + the front-end, so we only check it here to avoid regressions. */ if (sym->backend_decl) { - /* This becomes the nominal_type in - function.c:assign_parm_find_data_types. */ - TREE_TYPE (sym->backend_decl) = unsigned_char_type_node; - /* This becomes the passed_type in - function.c:assign_parm_find_data_types. C promotes char to - integer for argument passing. */ - DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node; - - DECL_BY_REFERENCE (sym->backend_decl) = 0; + gcc_assert (TREE_CODE (TREE_TYPE (sym->backend_decl)) == INTEGER_TYPE); + gcc_assert (TYPE_UNSIGNED (TREE_TYPE (sym->backend_decl)) == 1); + gcc_assert (TYPE_PRECISION (TREE_TYPE (sym->backend_decl)) == CHAR_TYPE_SIZE); + gcc_assert (DECL_BY_REFERENCE (sym->backend_decl) == 0); } - if (expr != NULL) + /* If we have a constant character expression, make it into an + integer of type C char. */ + if ((*expr)->expr_type == EXPR_CONSTANT) { - /* If we have a constant character expression, make it into an - integer. */ - if ((*expr)->expr_type == EXPR_CONSTANT) - { - gfc_typespec ts; - gfc_clear_ts (&ts); + gfc_typespec ts; + gfc_clear_ts (&ts); - *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL, - (int)(*expr)->value.character.string[0]); - if ((*expr)->ts.kind != gfc_c_int_kind) - { - /* The expr needs to be compatible with a C int. If the - conversion fails, then the 2 causes an ICE. */ - ts.type = BT_INTEGER; - ts.kind = gfc_c_int_kind; - gfc_convert_type (*expr, &ts, 2); - } + *expr = gfc_get_int_expr (gfc_default_character_kind, NULL, + (*expr)->value.character.string[0]); + } + else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE) + { + if ((*expr)->ref == NULL) + { + se->expr = gfc_string_to_single_character + (build_int_cst (integer_type_node, 1), + gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind), + gfc_get_symbol_decl + ((*expr)->symtree->n.sym)), + (*expr)->ts.kind); } - else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE) - { - if ((*expr)->ref == NULL) - { - se->expr = gfc_string_to_single_character - (build_int_cst (integer_type_node, 1), - gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind), - gfc_get_symbol_decl - ((*expr)->symtree->n.sym)), - (*expr)->ts.kind); - } - else - { - gfc_conv_variable (se, *expr); - se->expr = gfc_string_to_single_character - (build_int_cst (integer_type_node, 1), - gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind), - se->expr), - (*expr)->ts.kind); - } + else + { + gfc_conv_variable (se, *expr); + se->expr = gfc_string_to_single_character + (build_int_cst (integer_type_node, 1), + gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind), + se->expr), + (*expr)->ts.kind); } } } @@ -6341,7 +6329,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, && fsym->ns->proc_name->attr.is_bind_c) { parmse.expr = NULL; - gfc_conv_scalar_char_value (fsym, &parmse, &e); + conv_scalar_char_value (fsym, &parmse, &e); if (parmse.expr == NULL) gfc_conv_expr (&parmse, e); } diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index eec4aa6..6262d52 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -2262,7 +2262,7 @@ gfc_sym_type (gfc_symbol * sym, bool is_bind_c) if (sym->ts.type == BT_CHARACTER && ((sym->attr.function && sym->attr.is_bind_c) - || (sym->attr.result + || ((sym->attr.result || sym->attr.value) && sym->ns->proc_name && sym->ns->proc_name->attr.is_bind_c) || (sym->ts.deferred && (!sym->ts.u.cl diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 15012a3..f78d502 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -508,7 +508,6 @@ void gfc_conv_expr_type (gfc_se * se, gfc_expr *, tree); tree gfc_get_character_len_in_bytes (tree); tree gfc_conv_scalar_to_descriptor (gfc_se *, tree, symbol_attribute); tree gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *, gfc_expr *); -void gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr); tree gfc_string_to_single_character (tree len, tree str, int kind); tree gfc_get_tree_for_caf_expr (gfc_expr *); void gfc_get_caf_token_offset (gfc_se*, tree *, tree *, tree, tree, gfc_expr *); diff --git a/gcc/testsuite/gfortran.dg/c_char_tests_3.f90 b/gcc/testsuite/gfortran.dg/c_char_tests_3.f90 new file mode 100644 index 0000000..9fc0714 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_char_tests_3.f90 @@ -0,0 +1,51 @@ +! { dg-do run } +! { dg-additional-sources c_char_tests_3_c.c } +! +! PR fortran/103828 +! Check that we can pass many function args as C char, which are interoperable +! with both INTEGER(C_SIGNED_CHAR) and CHARACTER(C_CHAR). + +subroutine test_int (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) bind(c) + use, intrinsic :: iso_c_binding + implicit none + integer(c_signed_char), value :: a, b, c, d, e, f, g, h, i, j, k, l, m, n, o + + if (a /= iachar('a')) stop 1 + if (b /= iachar('b')) stop 2 + if (c /= iachar('c')) stop 3 + if (d /= iachar('d')) stop 4 + if (e /= iachar('e')) stop 5 + if (f /= iachar('f')) stop 6 + if (g /= iachar('g')) stop 7 + if (h /= iachar('h')) stop 8 + if (i /= iachar('i')) stop 9 + if (j /= iachar('j')) stop 10 + if (k /= iachar('k')) stop 11 + if (l /= iachar('l')) stop 12 + if (m /= iachar('m')) stop 13 + if (n /= iachar('n')) stop 14 + if (o /= iachar('o')) stop 15 +end subroutine + +subroutine test_char (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) bind(c) + use, intrinsic :: iso_c_binding + implicit none + character(kind=c_char, len=1), value :: a, b, c, d, e, f, g, h, i, j, k, l, m, n, o + + if (a /= 'a') stop 101 + if (b /= 'b') stop 102 + if (c /= 'c') stop 103 + if (d /= 'd') stop 104 + if (e /= 'e') stop 105 + if (f /= 'f') stop 106 + if (g /= 'g') stop 107 + if (h /= 'h') stop 108 + if (i /= 'i') stop 109 + if (j /= 'j') stop 110 + if (k /= 'k') stop 111 + if (l /= 'l') stop 112 + if (m /= 'm') stop 113 + if (n /= 'n') stop 114 + if (o /= 'o') stop 115 +end subroutine + diff --git a/gcc/testsuite/gfortran.dg/c_char_tests_3_c.c b/gcc/testsuite/gfortran.dg/c_char_tests_3_c.c new file mode 100644 index 0000000..1c86a54 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_char_tests_3_c.c @@ -0,0 +1,16 @@ +void test_char (char, char, char, char, char, + char, char, char, char, char, + char, char, char, char, char); + +void test_int (char, char, char, char, char, + char, char, char, char, char, + char, char, char, char, char); + +int main (void) { + test_char ('a', 'b', 'c', 'd', 'e', + 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o'); + test_int ('a', 'b', 'c', 'd', 'e', + 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o'); +} diff --git a/gcc/testsuite/gfortran.dg/c_char_tests_4.f90 b/gcc/testsuite/gfortran.dg/c_char_tests_4.f90 new file mode 100644 index 0000000..512948a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_char_tests_4.f90 @@ -0,0 +1,90 @@ +! { dg-do run } +! +! PR fortran/103828 +! Check that we can pass many function args as C char, which are interoperable +! with both INTEGER(C_SIGNED_CHAR) and CHARACTER(C_CHAR). + +program test + use, intrinsic :: iso_c_binding, only : c_signed_char, c_char + implicit none + + interface + ! In order to perform this test, we cheat and pretend to give each function + ! the other one's prototype. It should still work, because all arguments + ! are interoperable with C char. + + subroutine test1 (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) bind(c, name='test_int') + import c_char + character(kind=c_char, len=1), value :: a, b, c, d, e, f, g, h, i, j, k, l, m, n, o + end subroutine test1 + + subroutine test2 (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) bind(c, name='test_char') + import c_signed_char + integer(kind=c_signed_char), value :: a, b, c, d, e, f, g, h, i, j, k, l, m, n, o + end subroutine test2 + + end interface + + call test1('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o') + call test2(ichar('a', kind=c_signed_char), & + ichar('b', kind=c_signed_char), & + ichar('c', kind=c_signed_char), & + ichar('d', kind=c_signed_char), & + ichar('e', kind=c_signed_char), & + ichar('f', kind=c_signed_char), & + ichar('g', kind=c_signed_char), & + ichar('h', kind=c_signed_char), & + ichar('i', kind=c_signed_char), & + ichar('j', kind=c_signed_char), & + ichar('k', kind=c_signed_char), & + ichar('l', kind=c_signed_char), & + ichar('m', kind=c_signed_char), & + ichar('n', kind=c_signed_char), & + ichar('o', kind=c_signed_char)) + +end program test + +subroutine test_int (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) bind(c) + use, intrinsic :: iso_c_binding, only : c_signed_char + implicit none + integer(c_signed_char), value :: a, b, c, d, e, f, g, h, i, j, k, l, m, n, o + + if (a /= iachar('a')) stop 1 + if (b /= iachar('b')) stop 2 + if (c /= iachar('c')) stop 3 + if (d /= iachar('d')) stop 4 + if (e /= iachar('e')) stop 5 + if (f /= iachar('f')) stop 6 + if (g /= iachar('g')) stop 7 + if (h /= iachar('h')) stop 8 + if (i /= iachar('i')) stop 9 + if (j /= iachar('j')) stop 10 + if (k /= iachar('k')) stop 11 + if (l /= iachar('l')) stop 12 + if (m /= iachar('m')) stop 13 + if (n /= iachar('n')) stop 14 + if (o /= iachar('o')) stop 15 +end subroutine + +subroutine test_char (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) bind(c) + use, intrinsic :: iso_c_binding, only : c_char + implicit none + character(kind=c_char, len=1), value :: a, b, c, d, e, f, g, h, i, j, k, l, m, n, o + + if (a /= 'a') stop 101 + if (b /= 'b') stop 102 + if (c /= 'c') stop 103 + if (d /= 'd') stop 104 + if (e /= 'e') stop 105 + if (f /= 'f') stop 106 + if (g /= 'g') stop 107 + if (h /= 'h') stop 108 + if (i /= 'i') stop 109 + if (j /= 'j') stop 110 + if (k /= 'k') stop 111 + if (l /= 'l') stop 112 + if (m /= 'm') stop 113 + if (n /= 'n') stop 114 + if (o /= 'o') stop 115 +end subroutine + diff --git a/gcc/testsuite/gfortran.dg/c_char_tests_5.f90 b/gcc/testsuite/gfortran.dg/c_char_tests_5.f90 new file mode 100644 index 0000000..c7a1c6e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_char_tests_5.f90 @@ -0,0 +1,49 @@ +! { dg-do run } +! { dg-options "-fbackslash" } +! +! PR fortran/103828 +! Check that we can C char with non-ASCII values, which are interoperable +! with both INTEGER(C_SIGNED_CHAR) and CHARACTER(C_CHAR). + +program test + use, intrinsic :: iso_c_binding, only : c_signed_char, c_char + implicit none + + interface + ! In order to perform this test, we cheat and pretend to give each function + ! the other one's prototype. It should still work, because all arguments + ! are interoperable with C char. + + subroutine test1 (a) bind(c, name='test_int') + import c_char + character(kind=c_char, len=1), value :: a + end subroutine test1 + + subroutine test2 (a) bind(c, name='test_char') + import c_signed_char + integer(kind=c_signed_char), value :: a + end subroutine test2 + + end interface + + call test1('\xA3') + call test2(-93_c_signed_char) + +end program test + +subroutine test_int (a) bind(c) + use, intrinsic :: iso_c_binding, only : c_signed_char + implicit none + integer(c_signed_char), value :: a + + if (a /= iachar('\xA3', kind=c_signed_char)) stop 1 +end subroutine + +subroutine test_char (a) bind(c) + use, intrinsic :: iso_c_binding, only : c_char + implicit none + character(kind=c_char, len=1), value :: a + + if (a /= '\xA3') stop 101 +end subroutine + -- cgit v1.1 From 054e57e467b15677966f832b491b1584feb194ee Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 29 Dec 2021 00:16:34 +0000 Subject: Daily bump. --- gcc/ChangeLog | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/ada/ChangeLog | 7 ++++++ gcc/d/ChangeLog | 8 +++++++ gcc/fortran/ChangeLog | 18 +++++++++++++++ gcc/go/ChangeLog | 4 ++++ gcc/jit/ChangeLog | 39 ++++++++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 40 +++++++++++++++++++++++++++++++++ 8 files changed, 176 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 72e36fe..3c37502 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,62 @@ +2021-12-28 Jason Merrill + + PR c++/99968 + * tree.c (verify_type): Allow enumerator with BOOLEAN_TYPE. + +2021-12-28 Jakub Jelinek + + PR middle-end/103813 + * fold-const.c (fold_truth_andor_1): Punt of const_binop LSHIFT_EXPR + or RSHIFT_EXPR returns NULL. Formatting fix. + +2021-12-28 Jakub Jelinek + + PR rtl-optimization/103837 + * loop-invariant.c (can_move_invariant_reg): Ignore DEBUG_INSNs in + the decisions whether to return false or continue and right before + returning true reset those debug insns that previously caused + returning false. + +2021-12-28 Jakub Jelinek + + PR debug/103838 + * optabs.c (expand_doubleword_mod, expand_doubleword_divmod): Only + check newly added insns for CALL_P, not the last insn of previous + code. + +2021-12-28 Martin Liska + + PR driver/103465 + * opts.c (finish_options): More part of diagnostics to ... + (diagnose_options): ... here. Call the function from both + finish_options and process_options. + * opts.h (diagnose_options): Declare. + * toplev.c (process_options): Call diagnose_options. + +2021-12-28 Martin Liska + + * doc/contrib.texi: Replace http:// with https. + * doc/contribute.texi: Likewise. + * doc/extend.texi: Likewise. + * doc/gccint.texi: Likewise. + * doc/gnu.texi: Likewise. + * doc/implement-c.texi: Likewise. + * doc/implement-cxx.texi: Likewise. + * doc/include/fdl.texi: Likewise. + * doc/include/gpl_v3.texi: Likewise. + * doc/install.texi: Likewise. + * doc/invoke.texi: Likewise. + * doc/passes.texi: Likewise. + * doc/service.texi: Likewise. + * doc/sourcebuild.texi: Likewise. + * doc/standards.texi: Likewise. + +2021-12-28 Jakub Jelinek + + PR target/103842 + * config/i386/mmx.md (divv2sf3): Use force_reg on op1. Always perform + divv4sf3 into a pseudo and emit_move_insn into operands[0]. + 2021-12-27 John David Anglin * config/pa/pa-protos.h: Delete diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 0802d0e..252ebb2 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20211228 +20211229 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 2ff37d0..41b6934 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2021-12-28 Martin Liska + + * doc/share/gnu_free_documentation_license.rst: Replace http:// with https. + * gnat-style.texi: Likewise. + * gnat_rm.texi: Likewise. + * gnat_ugn.texi: Likewise. + 2021-12-09 Jakub Jelinek PR pch/71934 diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index f878c33..dd41a50 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,11 @@ +2021-12-28 Martin Liska + + * gdc.texi: Use one more https. + +2021-12-28 Martin Liska + + * gdc.texi: Replace http:// with https. + 2021-12-20 Iain Buclaw * dmd/MERGE: Merge upstream dmd ad8412530. diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 687c808..65f52f3 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,21 @@ +2021-12-28 Francois-Xavier Coudert + + PR fortran/103828 + * trans-decl.c (generate_local_decl): Do not call + gfc_conv_scalar_char_value(), but check the type tree. + * trans-expr.c (gfc_conv_scalar_char_value): Rename to + conv_scalar_char_value, do not alter type tree. + (gfc_conv_procedure_call): Adjust call to renamed + conv_scalar_char_value() function. + * trans-types.c (gfc_sym_type): Take care of + CHARACTER(C_CHAR), VALUE arguments. + * trans.h (gfc_conv_scalar_char_value): Remove prototype. + +2021-12-28 Martin Liska + + * gfortran.texi: Replace http:// with https. + * intrinsic.texi: Likewise. + 2021-12-22 Harald Anlauf PR fortran/103778 diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 61ddd70..e540d16 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,7 @@ +2021-12-28 Martin Liska + + * gccgo.texi: Replace http:// with https. + 2021-11-29 Eric Gallager PR other/103021 diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog index 9f41007..3dd4c8d 100644 --- a/gcc/jit/ChangeLog +++ b/gcc/jit/ChangeLog @@ -1,3 +1,42 @@ +2021-12-28 Martin Liska + + * docs/_build/texinfo/libgccjit.texi: Replace http:// with https. + * docs/cp/index.rst: Likewise. + * docs/cp/intro/index.rst: Likewise. + * docs/cp/intro/tutorial01.rst: Likewise. + * docs/cp/intro/tutorial02.rst: Likewise. + * docs/cp/intro/tutorial03.rst: Likewise. + * docs/cp/intro/tutorial04.rst: Likewise. + * docs/cp/topics/asm.rst: Likewise. + * docs/cp/topics/compilation.rst: Likewise. + * docs/cp/topics/contexts.rst: Likewise. + * docs/cp/topics/expressions.rst: Likewise. + * docs/cp/topics/functions.rst: Likewise. + * docs/cp/topics/index.rst: Likewise. + * docs/cp/topics/locations.rst: Likewise. + * docs/cp/topics/objects.rst: Likewise. + * docs/cp/topics/types.rst: Likewise. + * docs/index.rst: Likewise. + * docs/internals/index.rst: Likewise. + * docs/intro/index.rst: Likewise. + * docs/intro/tutorial01.rst: Likewise. + * docs/intro/tutorial02.rst: Likewise. + * docs/intro/tutorial03.rst: Likewise. + * docs/intro/tutorial04.rst: Likewise. + * docs/intro/tutorial05.rst: Likewise. + * docs/topics/asm.rst: Likewise. + * docs/topics/compatibility.rst: Likewise. + * docs/topics/compilation.rst: Likewise. + * docs/topics/contexts.rst: Likewise. + * docs/topics/expressions.rst: Likewise. + * docs/topics/function-pointers.rst: Likewise. + * docs/topics/functions.rst: Likewise. + * docs/topics/index.rst: Likewise. + * docs/topics/locations.rst: Likewise. + * docs/topics/objects.rst: Likewise. + * docs/topics/performance.rst: Likewise. + * docs/topics/types.rst: Likewise. + 2021-12-20 Martin Liska * libgccjit.c (struct version_info): Rename to jit_version_info. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 97a46de..6c6a732 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,43 @@ +2021-12-28 Francois-Xavier Coudert + + PR fortran/103828 + * gfortran.dg/c_char_tests_3.f90: New file. + * gfortran.dg/c_char_tests_3_c.c: New file. + * gfortran.dg/c_char_tests_4.f90: New file. + * gfortran.dg/c_char_tests_5.f90: New file. + +2021-12-28 Jason Merrill + + PR c++/99968 + * g++.dg/ext/is_enum2.C: New test. + +2021-12-28 Jakub Jelinek + + PR middle-end/103813 + * gcc.c-torture/compile/pr103813.c: New test. + +2021-12-28 Jakub Jelinek + + PR rtl-optimization/103837 + * gcc.dg/pr103837.c: New test. + +2021-12-28 Jakub Jelinek + + PR debug/103838 + * gcc.dg/pr103838.c: New test. + +2021-12-28 Jakub Jelinek + + PR target/103842 + * g++.dg/opt/pr103842.C: New test. + +2021-12-28 Haochen Jiang + + * gcc.target/i386/amx-check.h (check_float_tile_register): + New check function for float to prevent precision loss. + * gcc.target/i386/amxbf16-dpbf16ps-2.c: Correct the type convert + and byte offset. Use the new check function. + 2021-12-27 Patrick Palka PR c++/101239 -- cgit v1.1 From 44372676e81358de29d5c853685a7664a95d8a96 Mon Sep 17 00:00:00 2001 From: Xionghu Luo Date: Tue, 28 Dec 2021 19:09:14 -0600 Subject: Fix ICE in lsplit when built with -O3 -fno-guess-branch-probability [PR103793] no-guess-branch-probability option requires profile_count scaling with initialized_p guard, use multiply instead of apply_scale, which will do the right thing to undefined probabilities and will not cause unnecesary roundoff errors and precision info loss. Also merge the missed part of r12-6086 of factor out function to avoid duplicate code. Regression testest pass on Power and X86. gcc/ChangeLog: PR tree-optimization/103793 * tree-ssa-loop-split.c (fix_loop_bb_probability): New function. (split_loop): Use multiply to scale loop1's exit probability. (do_split_loop_on_cond): Call fix_loop_bb_probability. gcc/testsuite/ChangeLog: PR tree-optimization/103793 * gcc.dg/pr103793.c: New test. --- gcc/testsuite/gcc.dg/pr103793.c | 12 ++++++ gcc/tree-ssa-loop-split.c | 86 +++++++++++++++++------------------------ 2 files changed, 48 insertions(+), 50 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr103793.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/pr103793.c b/gcc/testsuite/gcc.dg/pr103793.c new file mode 100644 index 0000000..d7ed721 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr103793.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-guess-branch-probability" } */ + +extern void bar (void); + +void +foo (int x, int w) +{ + for (int y; y < w; y++) + if (y < x) + bar (); +} diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c index 3312806..3e1bbc8 100644 --- a/gcc/tree-ssa-loop-split.c +++ b/gcc/tree-ssa-loop-split.c @@ -484,6 +484,39 @@ compute_new_first_bound (gimple_seq *stmts, class tree_niter_desc *niter, return newend; } +/* Fix the two loop's bb count after split based on the split edge probability, + don't adjust the bbs dominated by true branches of that loop to avoid + dropping 1s down. */ +static void +fix_loop_bb_probability (class loop *loop1, class loop *loop2, edge true_edge, + edge false_edge) +{ + update_ssa (TODO_update_ssa); + + /* Proportion first loop's bb counts except those dominated by true + branch to avoid drop 1s down. */ + basic_block *bbs1, *bbs2; + bbs1 = get_loop_body (loop1); + unsigned j; + for (j = 0; j < loop1->num_nodes; j++) + if (bbs1[j] == loop1->latch + || !dominated_by_p (CDI_DOMINATORS, bbs1[j], true_edge->dest)) + bbs1[j]->count + = bbs1[j]->count.apply_probability (true_edge->probability); + free (bbs1); + + /* Proportion second loop's bb counts except those dominated by false + branch to avoid drop 1s down. */ + basic_block bbi_copy = get_bb_copy (false_edge->dest); + bbs2 = get_loop_body (loop2); + for (j = 0; j < loop2->num_nodes; j++) + if (bbs2[j] == loop2->latch + || !dominated_by_p (CDI_DOMINATORS, bbs2[j], bbi_copy)) + bbs2[j]->count + = bbs2[j]->count.apply_probability (true_edge->probability.invert ()); + free (bbs2); +} + /* Checks if LOOP contains an conditional block whose condition depends on which side in the iteration space it is, and if so splits the iteration space into two loops. Returns true if the @@ -610,38 +643,14 @@ split_loop (class loop *loop1) tree guard_next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop1)); patch_loop_exit (loop1, guard_stmt, guard_next, newend, initial_true); - update_ssa (TODO_update_ssa); - - /* Proportion first loop's bb counts except those dominated by true - branch to avoid drop 1s down. */ - basic_block *bbs1, *bbs2; - bbs1 = get_loop_body (loop1); - unsigned j; - for (j = 0; j < loop1->num_nodes; j++) - if (bbs1[j] == loop1->latch - || !dominated_by_p (CDI_DOMINATORS, bbs1[j], true_edge->dest)) - bbs1[j]->count - = bbs1[j]->count.apply_probability (true_edge->probability); - free (bbs1); + fix_loop_bb_probability (loop1, loop2, true_edge, false_edge); /* Fix first loop's exit probability after scaling. */ edge exit_to_latch1 = single_pred_edge (loop1->latch); - exit_to_latch1->probability = exit_to_latch1->probability.apply_scale ( - true_edge->probability.to_reg_br_prob_base (), REG_BR_PROB_BASE); + exit_to_latch1->probability *= true_edge->probability; single_exit (loop1)->probability = exit_to_latch1->probability.invert (); - /* Proportion second loop's bb counts except those dominated by false - branch to avoid drop 1s down. */ - basic_block bbi_copy = get_bb_copy (false_edge->dest); - bbs2 = get_loop_body (loop2); - for (j = 0; j < loop2->num_nodes; j++) - if (bbs2[j] == loop2->latch - || !dominated_by_p (CDI_DOMINATORS, bbs2[j], bbi_copy)) - bbs2[j]->count = bbs2[j]->count.apply_probability ( - true_edge->probability.invert ()); - free (bbs2); - /* Finally patch out the two copies of the condition to be always true/false (or opposite). */ gcond *force_true = as_a (last_stmt (bbs[i])); @@ -1570,40 +1579,17 @@ do_split_loop_on_cond (struct loop *loop1, edge invar_branch) between loop1 and loop2. */ connect_loop_phis (loop1, loop2, to_loop2); - update_ssa (TODO_update_ssa); - edge true_edge, false_edge, skip_edge1, skip_edge2; extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge); - /* Proportion first loop's bb counts except those dominated by true - branch to avoid drop 1s down. */ skip_edge1 = true_invar ? false_edge : true_edge; skip_edge2 = true_invar ? true_edge : false_edge; - basic_block *bbs1, *bbs2; - bbs1 = get_loop_body (loop1); - unsigned j; - for (j = 0; j < loop1->num_nodes; j++) - if (bbs1[j] == loop1->latch - || !dominated_by_p (CDI_DOMINATORS, bbs1[j], skip_edge1->dest)) - bbs1[j]->count - = bbs1[j]->count.apply_probability (skip_edge1->probability); - free (bbs1); + fix_loop_bb_probability (loop1, loop2, skip_edge1, skip_edge2); /* Fix first loop's exit probability after scaling. */ to_loop1->probability = invar_branch->probability.invert (); to_loop2->probability = invar_branch->probability; - /* Proportion second loop's bb counts except those dominated by false - branch to avoid drop 1s down. */ - basic_block bbi_copy = get_bb_copy (skip_edge2->dest); - bbs2 = get_loop_body (loop2); - for (j = 0; j < loop2->num_nodes; j++) - if (bbs2[j] == loop2->latch - || !dominated_by_p (CDI_DOMINATORS, bbs2[j], bbi_copy)) - bbs2[j]->count - = bbs2[j]->count.apply_probability (skip_edge2->probability); - free (bbs2); - free_original_copy_tables (); return true; -- cgit v1.1 From 52a6b06c26346cfb6972252ef547720b431844e6 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 29 Dec 2021 09:34:32 +0100 Subject: i386: Robustify some expanders w.r.t. paradoxical SUBREGs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit lowpart_subreg might fail in some cases when trying to create paradoxical SUBREGs. Use force_reg on input operand, use new temporary output operand and emit move into the destination afterwards. Also, replace simplify_gen_subreg (Mx, op, My, 0) with equivalent lowpart_subreg (Mx, op, My). 2021-12-29 Uroš Bizjak gcc/ChangeLog: * config/i386/sse.md (vec_pack_float_): Perform gen_avx512dq_floatv2div2sf2 into a pseudo and emit move insn into operands[0]. (fix_truncv2sfv2di2): Use lowpart_subreg instead of simplify_gen_subreg. (trunc2): Perform gen_avx512vl_truncatevqi2 into a pseudo and emit move insn into operands[0]. (trunc2): Perform gen_avx512vl_truncatevhi2 into a pseudo and emit move insn into operands[0]. (truncv2div2si2): Perform gen_avx512vl_truncatev2div2si2 into a pseudo and emit move insn into operands[0]. (truncv8div8qi2): Perform gen_avx512f_truncatev8div16qi2 into a pseudo and emit move insn into operands[0]. (v8qiv8hi2): Use lowpart_subreg instead of simplify_gen_subreg. (v8qiv8si2): Ditto. (v4qiv4si2): Ditto. (v4hiv4si2): Ditto. (v8qiv8di2): Ditto. (v4qiv4di2): Ditto. (v2qiv2di2): Ditto. (v4hiv4di2): Ditto. (v2hiv2di2): Ditto. (v2siv2di2): Ditto. --- gcc/config/i386/sse.md | 115 ++++++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 50 deletions(-) (limited to 'gcc') diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 69c7547..0997d9e 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -8115,9 +8115,12 @@ (any_float:V2SF (match_operand:V2DI 1 "nonimmediate_operand")))] "TARGET_AVX512DQ && TARGET_AVX512VL" { - operands[0] = simplify_gen_subreg (V4SFmode, operands[0], V2SFmode, 0); + rtx op0 = gen_reg_rtx (V4SFmode); + emit_insn (gen_avx512dq_floatv2div2sf2 - (operands[0], operands[1])); + (op0, operands[1])); + + emit_move_insn (operands[0], lowpart_subreg (V2SFmode, op0, V4SFmode)); DONE; }) @@ -8547,10 +8550,10 @@ (match_operand:V2SF 1 "register_operand")))] "TARGET_AVX512DQ && TARGET_AVX512VL" { - operands[1] = force_reg (V2SFmode, operands[1]); - operands[1] = simplify_gen_subreg (V4SFmode, operands[1], V2SFmode, 0); + rtx op1 = force_reg (V2SFmode, operands[1]); + op1 = lowpart_subreg (V4SFmode, op1, V2SFmode); emit_insn (gen_avx512dq_fix_truncv2sfv2di2 - (operands[0], operands[1])); + (operands[0], op1)); DONE; }) @@ -13631,10 +13634,13 @@ (match_operand:PMOV_SRC_MODE_3 1 "register_operand")))] "TARGET_AVX512VL" { - operands[0] = simplify_gen_subreg (V16QImode, operands[0], mode, 0); - emit_insn (gen_avx512vl_truncatevqi2 (operands[0], - operands[1], - CONST0_RTX (mode))); + rtx op0 = gen_reg_rtx (V16QImode); + + emit_insn (gen_avx512vl_truncatevqi2 + (op0, operands[1], CONST0_RTX (mode))); + + emit_move_insn (operands[0], + lowpart_subreg (mode, op0, V16QImode)); DONE; }) @@ -14006,12 +14012,14 @@ (match_operand:PMOV_SRC_MODE_4 1 "register_operand")))] "TARGET_AVX512VL" { - operands[0] = simplify_gen_subreg (V8HImode, operands[0], mode, 0); - emit_insn (gen_avx512vl_truncatevhi2 (operands[0], - operands[1], - CONST0_RTX (mode))); - DONE; + rtx op0 = gen_reg_rtx (V8HImode); + + emit_insn (gen_avx512vl_truncatevhi2 + (op0, operands[1], CONST0_RTX (mode))); + emit_move_insn (operands[0], + lowpart_subreg (mode, op0, V8HImode)); + DONE; }) (define_insn "avx512vl_vhi2" @@ -14251,10 +14259,13 @@ (match_operand:V2DI 1 "register_operand")))] "TARGET_AVX512VL" { - operands[0] = simplify_gen_subreg (V4SImode, operands[0], V2SImode, 0); - emit_insn (gen_avx512vl_truncatev2div2si2 (operands[0], - operands[1], - CONST0_RTX (V2SImode))); + rtx op0 = gen_reg_rtx (V4SImode); + + emit_insn (gen_avx512vl_truncatev2div2si2 + (op0, operands[1], CONST0_RTX (V2SImode))); + + emit_move_insn (operands[0], + lowpart_subreg (V2SImode, op0, V4SImode)); DONE; }) @@ -14389,8 +14400,12 @@ (match_operand:V8DI 1 "register_operand")))] "TARGET_AVX512F" { - operands[0] = simplify_gen_subreg (V16QImode, operands[0], V8QImode, 0); - emit_insn (gen_avx512f_truncatev8div16qi2 (operands[0], operands[1])); + rtx op0 = gen_reg_rtx (V16QImode); + + emit_insn (gen_avx512f_truncatev8div16qi2 (op0, operands[1])); + + emit_move_insn (operands[0], + lowpart_subreg (V8QImode, op0, V16QImode)); DONE; }) @@ -21625,9 +21640,9 @@ { if (!MEM_P (operands[1])) { - operands[1] = force_reg (V8QImode, operands[1]); - operands[1] = simplify_gen_subreg (V16QImode, operands[1], V8QImode, 0); - emit_insn (gen_sse4_1_v8qiv8hi2 (operands[0], operands[1])); + rtx op1 = force_reg (V8QImode, operands[1]); + op1 = lowpart_subreg (V16QImode, op1, V8QImode); + emit_insn (gen_sse4_1_v8qiv8hi2 (operands[0], op1)); DONE; } }) @@ -21703,9 +21718,9 @@ { if (!MEM_P (operands[1])) { - operands[1] = force_reg (V8QImode, operands[1]); - operands[1] = simplify_gen_subreg (V16QImode, operands[1], V8QImode, 0); - emit_insn (gen_avx2_v8qiv8si2 (operands[0], operands[1])); + rtx op1 = force_reg (V8QImode, operands[1]); + op1 = lowpart_subreg (V16QImode, op1, V8QImode); + emit_insn (gen_avx2_v8qiv8si2 (operands[0], op1)); DONE; } }) @@ -21767,9 +21782,9 @@ { if (!MEM_P (operands[1])) { - operands[1] = force_reg (V4QImode, operands[1]); - operands[1] = simplify_gen_subreg (V16QImode, operands[1], V4QImode, 0); - emit_insn (gen_sse4_1_v4qiv4si2 (operands[0], operands[1])); + rtx op1 = force_reg (V4QImode, operands[1]); + op1 = lowpart_subreg (V16QImode, op1, V4QImode); + emit_insn (gen_sse4_1_v4qiv4si2 (operands[0], op1)); DONE; } }) @@ -21935,9 +21950,9 @@ { if (!MEM_P (operands[1])) { - operands[1] = force_reg (V4HImode, operands[1]); - operands[1] = simplify_gen_subreg (V8HImode, operands[1], V4HImode, 0); - emit_insn (gen_sse4_1_v4hiv4si2 (operands[0], operands[1])); + rtx op1 = force_reg (V4HImode, operands[1]); + op1 = lowpart_subreg (V8HImode, op1, V4HImode); + emit_insn (gen_sse4_1_v4hiv4si2 (operands[0], op1)); DONE; } }) @@ -22056,9 +22071,9 @@ { if (!MEM_P (operands[1])) { - operands[1] = force_reg (V8QImode, operands[1]); - operands[1] = simplify_gen_subreg (V16QImode, operands[1], V8QImode, 0); - emit_insn (gen_avx512f_v8qiv8di2 (operands[0], operands[1])); + rtx op1 = force_reg (V8QImode, operands[1]); + op1 = lowpart_subreg (V16QImode, op1, V8QImode); + emit_insn (gen_avx512f_v8qiv8di2 (operands[0], op1)); DONE; } }) @@ -22118,9 +22133,9 @@ { if (!MEM_P (operands[1])) { - operands[1] = force_reg (V4QImode, operands[1]); - operands[1] = simplify_gen_subreg (V16QImode, operands[1], V4QImode, 0); - emit_insn (gen_avx2_v4qiv4di2 (operands[0], operands[1])); + rtx op1 = force_reg (V4QImode, operands[1]); + op1 = lowpart_subreg (V16QImode, operands[1], V4QImode); + emit_insn (gen_avx2_v4qiv4di2 (operands[0], op1)); DONE; } }) @@ -22145,9 +22160,9 @@ (match_operand:V2QI 1 "register_operand")))] "TARGET_SSE4_1" { - operands[1] = force_reg (V2QImode, operands[1]); - operands[1] = simplify_gen_subreg (V16QImode, operands[1], V2QImode, 0); - emit_insn (gen_sse4_1_v2qiv2di2 (operands[0], operands[1])); + rtx op1 = force_reg (V2QImode, operands[1]); + op1 = lowpart_subreg (V16QImode, op1, V2QImode); + emit_insn (gen_sse4_1_v2qiv2di2 (operands[0], op1)); DONE; }) @@ -22218,9 +22233,9 @@ { if (!MEM_P (operands[1])) { - operands[1] = force_reg (V4HImode, operands[1]); - operands[1] = simplify_gen_subreg (V8HImode, operands[1], V4HImode, 0); - emit_insn (gen_avx2_v4hiv4di2 (operands[0], operands[1])); + rtx op1 = force_reg (V4HImode, operands[1]); + op1 = lowpart_subreg (V8HImode, op1, V4HImode); + emit_insn (gen_avx2_v4hiv4di2 (operands[0], op1)); DONE; } }) @@ -22280,9 +22295,9 @@ { if (!MEM_P (operands[1])) { - operands[1] = force_reg (V2HImode, operands[1]); - operands[1] = simplify_gen_subreg (V8HImode, operands[1], V2HImode, 0); - emit_insn (gen_sse4_1_v2hiv2di2 (operands[0], operands[1])); + rtx op1 = force_reg (V2HImode, operands[1]); + op1 = lowpart_subreg (V8HImode, op1, V2HImode); + emit_insn (gen_sse4_1_v2hiv2di2 (operands[0], op1)); DONE; } }) @@ -22497,9 +22512,9 @@ { if (!MEM_P (operands[1])) { - operands[1] = force_reg (V2SImode, operands[1]); - operands[1] = simplify_gen_subreg (V4SImode, operands[1], V2SImode, 0); - emit_insn (gen_sse4_1_v2siv2di2 (operands[0], operands[1])); + rtx op1 = force_reg (V2SImode, operands[1]); + op1 = lowpart_subreg (V4SImode, op1, V2SImode); + emit_insn (gen_sse4_1_v2siv2di2 (operands[0], op1)); DONE; } }) -- cgit v1.1 From ad964f7eaef9c03ce68a01cfdd7fde9d56524868 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 21 Dec 2021 17:43:55 +0100 Subject: Support ld.mold linker. gcc/ChangeLog: * collect2.c (main): Add ld.mold. * common.opt: Add -fuse-ld=mold. * doc/invoke.texi: Document it. * gcc.c (driver_handle_option): Handle -fuse-ld=mold. * opts.c (common_handle_option): Likewise. --- gcc/collect2.c | 10 +++++++--- gcc/common.opt | 4 ++++ gcc/doc/invoke.texi | 4 ++++ gcc/gcc.c | 4 ++++ gcc/opts.c | 1 + 5 files changed, 20 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/collect2.c b/gcc/collect2.c index d47fe3f..b322527 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -776,6 +776,7 @@ main (int argc, char **argv) USE_GOLD_LD, USE_BFD_LD, USE_LLD_LD, + USE_MOLD_LD, USE_LD_MAX } selected_linker = USE_DEFAULT_LD; static const char *const ld_suffixes[USE_LD_MAX] = @@ -784,7 +785,8 @@ main (int argc, char **argv) PLUGIN_LD_SUFFIX, "ld.gold", "ld.bfd", - "ld.lld" + "ld.lld", + "ld.mold" }; static const char *const real_ld_suffix = "real-ld"; static const char *const collect_ld_suffix = "collect-ld"; @@ -957,6 +959,8 @@ main (int argc, char **argv) selected_linker = USE_GOLD_LD; else if (strcmp (argv[i], "-fuse-ld=lld") == 0) selected_linker = USE_LLD_LD; + else if (strcmp (argv[i], "-fuse-ld=mold") == 0) + selected_linker = USE_MOLD_LD; else if (startswith (argv[i], "-o")) { /* Parse the output filename if it's given so that we can make @@ -1048,7 +1052,7 @@ main (int argc, char **argv) ld_file_name = 0; #ifdef DEFAULT_LINKER if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD || - selected_linker == USE_LLD_LD) + selected_linker == USE_LLD_LD || selected_linker == USE_MOLD_LD) { char *linker_name; # ifdef HOST_EXECUTABLE_SUFFIX @@ -1283,7 +1287,7 @@ main (int argc, char **argv) else if (!use_collect_ld && startswith (arg, "-fuse-ld=")) { - /* Do not pass -fuse-ld={bfd|gold|lld} to the linker. */ + /* Do not pass -fuse-ld={bfd|gold|lld|mold} to the linker. */ ld1--; ld2--; } diff --git a/gcc/common.opt b/gcc/common.opt index 2ed818d..dba3fa8 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -3046,6 +3046,10 @@ fuse-ld=lld Common Driver Negative(fuse-ld=lld) Use the lld LLVM linker instead of the default linker. +fuse-ld=mold +Common Driver Negative(fuse-ld=mold) +Use the Modern linker (MOLD) linker instead of the default linker. + fuse-linker-plugin Common Undocumented Var(flag_use_linker_plugin) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index e644c63..54fa75b 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -16266,6 +16266,10 @@ Use the @command{gold} linker instead of the default linker. @opindex fuse-ld=lld Use the LLVM @command{lld} linker instead of the default linker. +@item -fuse-ld=mold +@opindex fuse-ld=mold +Use the Modern Linker (@command{mold}) instead of the default linker. + @cindex Libraries @item -l@var{library} @itemx -l @var{library} diff --git a/gcc/gcc.c b/gcc/gcc.c index b75b50b..06e18a7 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -4282,6 +4282,10 @@ driver_handle_option (struct gcc_options *opts, use_ld = ".gold"; break; + case OPT_fuse_ld_mold: + use_ld = ".mold"; + break; + case OPT_fcompare_debug_second: compare_debug_second = 1; break; diff --git a/gcc/opts.c b/gcc/opts.c index e4e47ff..f820052 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -3105,6 +3105,7 @@ common_handle_option (struct gcc_options *opts, case OPT_fuse_ld_bfd: case OPT_fuse_ld_gold: case OPT_fuse_ld_lld: + case OPT_fuse_ld_mold: case OPT_fuse_linker_plugin: /* No-op. Used by the driver and passed to us because it starts with f.*/ break; -- cgit v1.1