diff options
author | Martin Liska <mliska@suse.cz> | 2022-08-09 15:30:09 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-08-09 15:30:09 +0200 |
commit | 9fce2fbb1dff9f090d98a056df1da459ba45f16f (patch) | |
tree | 097d3bc54e8fd0f304bb8c4d99667289e9f3fd25 /gcc | |
parent | b3a187edd33b89acf19ba46f3b8070d7c977ac57 (diff) | |
parent | 04284176d549ff2565406406a6d53ab4ba8e507d (diff) | |
download | gcc-9fce2fbb1dff9f090d98a056df1da459ba45f16f.zip gcc-9fce2fbb1dff9f090d98a056df1da459ba45f16f.tar.gz gcc-9fce2fbb1dff9f090d98a056df1da459ba45f16f.tar.bz2 |
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc')
49 files changed, 679 insertions, 138 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2d41c22..36879ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,29 @@ +2022-08-08 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/106556 + * gimple-range-gori.cc (gori_compute::condexpr_adjust): Use the + type of the cond_expr operands being evaluted. + +2022-08-08 Tom Honermann <tom@honermann.net> + + * ginclude/stdatomic.h (atomic_char8_t, + ATOMIC_CHAR8_T_LOCK_FREE): New typedef and macro. + +2022-08-08 Andrew Pinski <apinski@marvell.com> + + PR middle-end/103645 + * gimplify.cc (gimplify_init_constructor): Don't build/add + gimple assignment of an empty type. + +2022-08-08 Richard Biener <rguenther@suse.de> + + PR lto/106540 + PR lto/106334 + * dwarf2out.cc (dwarf2out_register_external_die): Restore + original assert. + * lto-streamer-in.cc (lto_read_tree_1): Use lto_input_tree_1 + to input DECL_INITIAL, avoiding to commit drefs. + 2022-08-07 Roger Sayle <roger@nextmovesoftware.com> * config/i386/i386.md (*cmp<dwi>_doubleword): Change predicate diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 00f22f5..8bd1173 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20220808 +20220809 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 68fc6e2..63277a5 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,17 @@ +2022-08-08 Tom Honermann <tom@honermann.net> + + PR preprocessor/106426 + * c-opts.cc (c_common_post_options): Assign cpp_opts->unsigned_utf8char + subject to -fchar8_t, -fsigned-char, and/or -funsigned-char. + +2022-08-08 Tom Honermann <tom@honermann.net> + + * c-lex.cc (lex_string, lex_charconst): Use char8_t as the type + of CPP_UTF8CHAR and CPP_UTF8STRING when char8_t support is + enabled. + * c-opts.cc (c_common_post_options): Set flag_char8_t if + targeting C2x. + 2022-07-31 Lewis Hyatt <lhyatt@gmail.com> PR c++/66290 diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc index 8bfa4f4..0b6f94e 100644 --- a/gcc/c-family/c-lex.cc +++ b/gcc/c-family/c-lex.cc @@ -1352,7 +1352,14 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate) default: case CPP_STRING: case CPP_UTF8STRING: - value = build_string (1, ""); + if (type == CPP_UTF8STRING && flag_char8_t) + { + value = build_string (TYPE_PRECISION (char8_type_node) + / TYPE_PRECISION (char_type_node), + ""); /* char8_t is 8 bits */ + } + else + value = build_string (1, ""); break; case CPP_STRING16: value = build_string (TYPE_PRECISION (char16_type_node) @@ -1425,9 +1432,7 @@ lex_charconst (const cpp_token *token) type = char16_type_node; else if (token->type == CPP_UTF8CHAR) { - if (!c_dialect_cxx ()) - type = unsigned_char_type_node; - else if (flag_char8_t) + if (flag_char8_t) type = char8_type_node; else type = char_type_node; diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index 4e14636..9833e50 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -1059,9 +1059,10 @@ c_common_post_options (const char **pfilename) if (flag_sized_deallocation == -1) flag_sized_deallocation = (cxx_dialect >= cxx14); - /* char8_t support is new in C++20. */ + /* char8_t support is implicitly enabled in C++20 and C2X. */ if (flag_char8_t == -1) - flag_char8_t = (cxx_dialect >= cxx20); + flag_char8_t = (cxx_dialect >= cxx20) || flag_isoc2x; + cpp_opts->unsigned_utf8char = flag_char8_t ? 1 : cpp_opts->unsigned_char; if (flag_extern_tls_init) { diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index cffb462..b5ecf92 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,11 @@ +2022-08-08 Tom Honermann <tom@honermann.net> + + * c-parser.cc (c_parser_string_literal): Use char8_t as the type + of CPP_UTF8STRING when char8_t support is enabled. + * c-typeck.cc (digest_init): Allow initialization of an array + of character type by a string literal with type array of + char8_t. + 2022-08-01 David Malcolm <dmalcolm@redhat.com> * c-typeck.cc (build_c_cast): Quote names of address spaces in diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 92049d1..fa93959 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -7447,7 +7447,14 @@ c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok) default: case CPP_STRING: case CPP_UTF8STRING: - value = build_string (1, ""); + if (type == CPP_UTF8STRING && flag_char8_t) + { + value = build_string (TYPE_PRECISION (char8_type_node) + / TYPE_PRECISION (char_type_node), + ""); /* char8_t is 8 bits */ + } + else + value = build_string (1, ""); break; case CPP_STRING16: value = build_string (TYPE_PRECISION (char16_type_node) @@ -7472,9 +7479,14 @@ c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok) { default: case CPP_STRING: - case CPP_UTF8STRING: TREE_TYPE (value) = char_array_type_node; break; + case CPP_UTF8STRING: + if (flag_char8_t) + TREE_TYPE (value) = char8_array_type_node; + else + TREE_TYPE (value) = char_array_type_node; + break; case CPP_STRING16: TREE_TYPE (value) = char16_array_type_node; break; diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 8514488..d37de2a 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -8056,7 +8056,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, if (char_array) { - if (typ2 != char_type_node) + if (typ2 != char_type_node && typ2 != char8_type_node) incompat_string_cst = true; } else if (!comptypes (typ1, typ2)) diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc index 6fc20d3..96295e2 100644 --- a/gcc/config/gcn/gcn.cc +++ b/gcc/config/gcn/gcn.cc @@ -2284,7 +2284,7 @@ gcn_function_value (const_tree valtype, const_tree, bool) && GET_MODE_SIZE (mode) < 4) mode = SImode; - return gen_rtx_REG (mode, SGPR_REGNO (RETURN_VALUE_REG)); + return gen_rtx_REG (mode, RETURN_VALUE_REG); } /* Implement TARGET_FUNCTION_VALUE_REGNO_P. @@ -2308,7 +2308,9 @@ num_arg_regs (const function_arg_info &arg) return 0; int size = arg.promoted_size_in_bytes (); - return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; + int regsize = UNITS_PER_WORD * (VECTOR_MODE_P (arg.mode) + ? GET_MODE_NUNITS (arg.mode) : 1); + return (size + regsize - 1) / regsize; } /* Implement TARGET_STRICT_ARGUMENT_NAMING. @@ -2358,16 +2360,16 @@ gcn_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) if (targetm.calls.must_pass_in_stack (arg)) return 0; - /* Vector parameters are not supported yet. */ - if (VECTOR_MODE_P (arg.mode)) - return 0; - - int reg_num = FIRST_PARM_REG + cum->num; + int first_reg = (VECTOR_MODE_P (arg.mode) + ? FIRST_VPARM_REG : FIRST_PARM_REG); + int cum_num = (VECTOR_MODE_P (arg.mode) + ? cum->vnum : cum->num); + int reg_num = first_reg + cum_num; int num_regs = num_arg_regs (arg); if (num_regs > 0) while (reg_num % num_regs != 0) reg_num++; - if (reg_num + num_regs <= FIRST_PARM_REG + NUM_PARM_REGS) + if (reg_num + num_regs <= first_reg + NUM_PARM_REGS) return gen_rtx_REG (arg.mode, reg_num); } else @@ -2419,11 +2421,15 @@ gcn_function_arg_advance (cumulative_args_t cum_v, if (!arg.named) return; + int first_reg = (VECTOR_MODE_P (arg.mode) + ? FIRST_VPARM_REG : FIRST_PARM_REG); + int *cum_num = (VECTOR_MODE_P (arg.mode) + ? &cum->vnum : &cum->num); int num_regs = num_arg_regs (arg); if (num_regs > 0) - while ((FIRST_PARM_REG + cum->num) % num_regs != 0) - cum->num++; - cum->num += num_regs; + while ((first_reg + *cum_num) % num_regs != 0) + (*cum_num)++; + *cum_num += num_regs; } else { @@ -2454,14 +2460,18 @@ gcn_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg) if (targetm.calls.must_pass_in_stack (arg)) return 0; - if (cum->num >= NUM_PARM_REGS) + int cum_num = (VECTOR_MODE_P (arg.mode) ? cum->vnum : cum->num); + int regsize = UNITS_PER_WORD * (VECTOR_MODE_P (arg.mode) + ? GET_MODE_NUNITS (arg.mode) : 1); + + if (cum_num >= NUM_PARM_REGS) return 0; /* If the argument fits entirely in registers, return 0. */ - if (cum->num + num_arg_regs (arg) <= NUM_PARM_REGS) + if (cum_num + num_arg_regs (arg) <= NUM_PARM_REGS) return 0; - return (NUM_PARM_REGS - cum->num) * UNITS_PER_WORD; + return (NUM_PARM_REGS - cum_num) * regsize; } /* A normal function which takes a pointer argument (to a scalar) may be @@ -2549,14 +2559,11 @@ gcn_return_in_memory (const_tree type, const_tree ARG_UNUSED (fntype)) if (AGGREGATE_TYPE_P (type)) return true; - /* Vector return values are not supported yet. */ - if (VECTOR_TYPE_P (type)) - return true; - if (mode == BLKmode) return true; - if (size > 2 * UNITS_PER_WORD) + if ((!VECTOR_TYPE_P (type) && size > 2 * UNITS_PER_WORD) + || size > 2 * UNITS_PER_WORD * 64) return true; return false; @@ -3199,9 +3206,10 @@ gcn_expand_epilogue (void) emit_move_insn (kernarg_reg, retptr_mem); rtx retval_mem = gen_rtx_MEM (SImode, kernarg_reg); + rtx scalar_retval = gen_rtx_REG (SImode, FIRST_PARM_REG); set_mem_addr_space (retval_mem, ADDR_SPACE_SCALAR_FLAT); - emit_move_insn (retval_mem, - gen_rtx_REG (SImode, SGPR_REGNO (RETURN_VALUE_REG))); + emit_move_insn (scalar_retval, gen_rtx_REG (SImode, RETURN_VALUE_REG)); + emit_move_insn (retval_mem, scalar_retval); } emit_jump_insn (gen_gcn_return ()); diff --git a/gcc/config/gcn/gcn.h b/gcc/config/gcn/gcn.h index a129760..318256c 100644 --- a/gcc/config/gcn/gcn.h +++ b/gcc/config/gcn/gcn.h @@ -138,7 +138,7 @@ #define LINK_REGNUM 18 #define EXEC_SAVE_REG 20 #define CC_SAVE_REG 22 -#define RETURN_VALUE_REG 24 /* Must be divisible by 4. */ +#define RETURN_VALUE_REG 168 /* Must be divisible by 4. */ #define STATIC_CHAIN_REGNUM 30 #define WORK_ITEM_ID_Z_REG 162 #define SOFT_ARG_REG 416 @@ -146,7 +146,8 @@ #define DWARF_LINK_REGISTER 420 #define FIRST_PSEUDO_REGISTER 421 -#define FIRST_PARM_REG 24 +#define FIRST_PARM_REG (FIRST_SGPR_REG + 24) +#define FIRST_VPARM_REG (FIRST_VGPR_REG + 8) #define NUM_PARM_REGS 6 /* There is no arg pointer. Just choose random fixed register that does @@ -164,7 +165,8 @@ #define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X))) #define CC_REGNO_P(X) ((X) == SCC_REG || (X) == VCC_REG) #define FUNCTION_ARG_REGNO_P(N) \ - ((N) >= FIRST_PARM_REG && (N) < (FIRST_PARM_REG + NUM_PARM_REGS)) + (((N) >= FIRST_PARM_REG && (N) < (FIRST_PARM_REG + NUM_PARM_REGS)) \ + || ((N) >= FIRST_VPARM_REG && (N) < (FIRST_VPARM_REG + NUM_PARM_REGS))) #define FIXED_REGISTERS { \ @@ -550,6 +552,7 @@ typedef struct gcn_args tree fntype; struct gcn_kernel_args args; int num; + int vnum; int offset; int alignment; } CUMULATIVE_ARGS; @@ -653,7 +656,7 @@ enum gcn_builtin_codes } /* This needs to match gcn_function_value. */ -#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, SGPR_REGNO (RETURN_VALUE_REG)) +#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, RETURN_VALUE_REG) /* The s_ff0 and s_flbit instructions return -1 if no input bits are set. */ #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 2) diff --git a/gcc/config/gcn/gcn.md b/gcc/config/gcn/gcn.md index 70a769b..7805e86 100644 --- a/gcc/config/gcn/gcn.md +++ b/gcc/config/gcn/gcn.md @@ -908,11 +908,11 @@ {}) (define_insn "gcn_call_value" - [(set (match_operand 0 "register_operand" "=Sg,Sg") - (call (mem (match_operand 1 "immediate_operand" "Y,B")) + [(set (match_operand 0 "register_operand" "=Sgv,Sgv") + (call (mem (match_operand 1 "immediate_operand" " Y, B")) (match_operand 2 "const_int_operand"))) (clobber (reg:DI LR_REGNUM)) - (clobber (match_scratch:DI 3 "=&Sg,X"))] + (clobber (match_scratch:DI 3 "=&Sg, X"))] "" "@ s_getpc_b64\t%3\;s_add_u32\t%L3, %L3, %1@rel32@lo+4\;s_addc_u32\t%H3, %H3, %1@rel32@hi+4\;s_swappc_b64\ts[18:19], %3 @@ -921,11 +921,11 @@ (set_attr "length" "24")]) (define_insn "gcn_call_value_indirect" - [(set (match_operand 0 "register_operand" "=Sg") - (call (mem (match_operand:DI 1 "register_operand" "Sg")) + [(set (match_operand 0 "register_operand" "=Sgv") + (call (mem (match_operand:DI 1 "register_operand" " Sg")) (match_operand 2 "" ""))) (clobber (reg:DI LR_REGNUM)) - (clobber (match_scratch:DI 3 "=X"))] + (clobber (match_scratch:DI 3 "= X"))] "" "s_swappc_b64\ts[18:19], %1" [(set_attr "type" "sop1") diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index 41e2809..0bb74b1 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,8 @@ +2022-08-08 Iain Buclaw <ibuclaw@gdcproject.org> + + PR d/106555 + * d-target.cc (Target::isReturnOnStack): Check for return type size. + 2022-08-03 Iain Buclaw <ibuclaw@gdcproject.org> * dmd/MERGE: Merge upstream dmd d7772a2369. diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc index 610be74..d4350e5 100644 --- a/gcc/d/d-target.cc +++ b/gcc/d/d-target.cc @@ -464,6 +464,8 @@ Target::isReturnOnStack (TypeFunction *tf, bool) return false; Type *tn = tf->next->toBasetype (); + if (tn->size () == SIZE_INVALID) + return false; return (tn->ty == TY::Tstruct || tn->ty == TY::Tsarray); } diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 58cea4d..0131b01 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -828,6 +828,10 @@ public: if (global.errors) return; + /* Start generating code for this function. */ + gcc_assert (d->semanticRun == PASS::semantic3done); + d->semanticRun = PASS::obj; + /* Duplicated FuncDeclarations map to the same symbol. Check if this is the one declaration which will be emitted. */ tree fndecl = get_symbol_decl (d); @@ -844,10 +848,6 @@ public: if (global.params.verbose) message ("function %s", d->toPrettyChars ()); - /* Start generating code for this function. */ - gcc_assert (d->semanticRun == PASS::semantic3done); - d->semanticRun = PASS::obj; - tree old_context = start_function (d); tree parm_decl = NULL_TREE; @@ -1020,13 +1020,103 @@ build_decl_tree (Dsymbol *d) input_location = saved_location; } +/* Returns true if function FD is defined or instantiated in a root module. */ + +static bool +function_defined_in_root_p (FuncDeclaration *fd) +{ + Module *md = fd->getModule (); + if (md && md->isRoot ()) + return true; + + TemplateInstance *ti = fd->isInstantiated (); + if (ti && ti->minst && ti->minst->isRoot ()) + return true; + + return false; +} + +/* Returns true if function FD always needs to be implicitly defined, such as + it was declared `pragma(inline)'. */ + +static bool +function_needs_inline_definition_p (FuncDeclaration *fd) +{ + /* Function has already been defined. */ + if (!DECL_EXTERNAL (fd->csym)) + return false; + + /* Non-inlineable functions are always external. */ + if (DECL_UNINLINABLE (fd->csym)) + return false; + + /* No function body available for inlining. */ + if (!fd->fbody) + return false; + + /* Ignore functions that aren't decorated with `pragma(inline)'. */ + if (fd->inlining != PINLINE::always) + return false; + + /* These functions are tied to the module they are defined in. */ + if (fd->isFuncLiteralDeclaration () + || fd->isUnitTestDeclaration () + || fd->isFuncAliasDeclaration () + || fd->isInvariantDeclaration ()) + return false; + + /* Check whether function will be regularly defined later in the current + translation unit. */ + if (function_defined_in_root_p (fd)) + return false; + + /* Weak functions cannot be inlined. */ + if (lookup_attribute ("weak", DECL_ATTRIBUTES (fd->csym))) + return false; + + /* Naked functions cannot be inlined. */ + if (lookup_attribute ("naked", DECL_ATTRIBUTES (fd->csym))) + return false; + + return true; +} + +/* If the variable or function declaration in DECL needs to be defined, call + build_decl_tree on it now before returning its back-end symbol. */ + +static tree +maybe_build_decl_tree (Declaration *decl) +{ + gcc_assert (decl->csym != NULL_TREE); + + /* Still running semantic analysis on declaration, or it has already had its + code generated. */ + if (doing_semantic_analysis_p || decl->semanticRun >= PASS::obj) + return decl->csym; + + if (error_operand_p (decl->csym)) + return decl->csym; + + if (FuncDeclaration *fd = decl->isFuncDeclaration ()) + { + /* Externally defined inline functions need to be emitted. */ + if (function_needs_inline_definition_p (fd)) + { + DECL_EXTERNAL (fd->csym) = 0; + build_decl_tree (fd); + } + } + + return decl->csym; +} + /* Return the decl for the symbol, create it if it doesn't already exist. */ tree get_symbol_decl (Declaration *decl) { if (decl->csym) - return decl->csym; + return maybe_build_decl_tree (decl); /* Deal with placeholder symbols immediately: SymbolDeclaration is used as a shell around an initializer symbol. */ @@ -1404,7 +1494,7 @@ get_symbol_decl (Declaration *decl) TREE_USED (decl->csym) = 1; d_keep (decl->csym); - return decl->csym; + return maybe_build_decl_tree (decl); } /* Returns a declaration for a VAR_DECL. Used to create compiler-generated @@ -1895,15 +1985,8 @@ start_function (FuncDeclaration *fd) /* Function has been defined, check now whether we intend to send it to object file, or it really is extern. Such as inlinable functions from modules not in this compilation, or thunk aliases. */ - TemplateInstance *ti = fd->isInstantiated (); - if (ti && ti->needsCodegen ()) + if (function_defined_in_root_p (fd)) DECL_EXTERNAL (fndecl) = 0; - else - { - Module *md = fd->getModule (); - if (md && md->isRoot ()) - DECL_EXTERNAL (fndecl) = 0; - } DECL_INITIAL (fndecl) = error_mark_node; @@ -2422,16 +2505,16 @@ set_linkage_for_decl (tree decl) if (!TREE_PUBLIC (decl)) return; - /* Don't need to give private or protected symbols a special linkage. */ - if ((TREE_PRIVATE (decl) || TREE_PROTECTED (decl)) - && !DECL_INSTANTIATED (decl)) - return; - /* Functions declared as `pragma(inline, true)' can appear in multiple translation units. */ if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)) return d_comdat_linkage (decl); + /* Don't need to give private or protected symbols a special linkage. */ + if ((TREE_PRIVATE (decl) || TREE_PROTECTED (decl)) + && !DECL_INSTANTIATED (decl)) + return; + /* If all instantiations must go in COMDAT, give them that linkage. This also applies to other extern declarations, so that it is possible for them to override template declarations. */ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index a48cca5..1c2caab 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -14717,6 +14717,13 @@ optimizing. Maximum number of statements allowed in a block that needs to be duplicated when threading jumps. +@item max-jump-thread-paths +The maximum number of paths to consider when searching for jump threading +opportunities. When arriving at a block incoming edges are only considered +if the number of paths to be searched sofar multiplied by the incoming +edge degree does not exhaust the specified maximum number of paths to +consider. + @item max-fields-for-field-sensitive Maximum number of fields in a structure treated in a field sensitive manner during pointer analysis. @@ -15218,9 +15225,6 @@ Emit instrumentation calls to __tsan_func_entry() and __tsan_func_exit(). Maximum number of instructions to copy when duplicating blocks on a finite state automaton jump thread path. -@item max-fsm-thread-length -Maximum number of basic blocks on a jump thread path. - @item threader-debug threader-debug=[none|all] Enables verbose dumping of the threader solver. diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index cfea9cf..e3920c8 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -6069,12 +6069,7 @@ dwarf2out_register_external_die (tree decl, const char *sym, if (!external_die_map) external_die_map = hash_map<tree, sym_off_pair>::create_ggc (1000); - /* When we do tree merging during WPA or with -flto-partition=none we - can end up re-using GC memory as there's currently no way to unregister - external DIEs. Ideally we'd register them only after merging finished - but allowing override here is easiest. See PR106334. */ - gcc_checking_assert (!(in_lto_p && !flag_wpa) - || !external_die_map->get (decl)); + gcc_checking_assert (!external_die_map->get (decl)); sym_off_pair p = { IDENTIFIER_POINTER (get_identifier (sym)), off }; external_die_map->put (decl, p); } diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index a43e44c..8879e44 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -1398,16 +1398,17 @@ gori_compute::condexpr_adjust (vrange &r1, vrange &r2, gimple *, tree cond, } // Now solve for SSA1 or SSA2 if they are in the dependency chain. - Value_Range tmp (type); if (ssa1 && in_chain_p (ssa1, cond_name)) { - if (compute_operand_range (tmp, def_stmt, cond_true, ssa1, src)) - r1.intersect (tmp); + Value_Range tmp1 (TREE_TYPE (ssa1)); + if (compute_operand_range (tmp1, def_stmt, cond_true, ssa1, src)) + r1.intersect (tmp1); } if (ssa2 && in_chain_p (ssa2, cond_name)) { - if (compute_operand_range (tmp, def_stmt, cond_false, ssa2, src)) - r2.intersect (tmp); + Value_Range tmp2 (TREE_TYPE (ssa2)); + if (compute_operand_range (tmp2, def_stmt, cond_false, ssa2, src)) + r2.intersect (tmp2); } if (idx) { diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 2ac7ca0..f0fbdb4 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -5488,8 +5488,11 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, if (ret == GS_ERROR) return GS_ERROR; /* If we have gimplified both sides of the initializer but have - not emitted an assignment, do so now. */ - if (*expr_p) + not emitted an assignment, do so now. */ + if (*expr_p + /* If the type is an empty type, we don't need to emit the + assignment. */ + && !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))) { tree lhs = TREE_OPERAND (*expr_p, 0); tree rhs = TREE_OPERAND (*expr_p, 1); diff --git a/gcc/ginclude/stdatomic.h b/gcc/ginclude/stdatomic.h index bfcfdf6..9f2475b 100644 --- a/gcc/ginclude/stdatomic.h +++ b/gcc/ginclude/stdatomic.h @@ -49,6 +49,9 @@ typedef _Atomic long atomic_long; typedef _Atomic unsigned long atomic_ulong; typedef _Atomic long long atomic_llong; typedef _Atomic unsigned long long atomic_ullong; +#ifdef __CHAR8_TYPE__ +typedef _Atomic __CHAR8_TYPE__ atomic_char8_t; +#endif typedef _Atomic __CHAR16_TYPE__ atomic_char16_t; typedef _Atomic __CHAR32_TYPE__ atomic_char32_t; typedef _Atomic __WCHAR_TYPE__ atomic_wchar_t; @@ -97,6 +100,9 @@ extern void atomic_signal_fence (memory_order); #define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE #define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE +#ifdef __GCC_ATOMIC_CHAR8_T_LOCK_FREE +#define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE +#endif #define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE #define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE #define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE diff --git a/gcc/lto-streamer-in.cc b/gcc/lto-streamer-in.cc index fe5a4e7..a7dad70 100644 --- a/gcc/lto-streamer-in.cc +++ b/gcc/lto-streamer-in.cc @@ -1699,11 +1699,14 @@ lto_read_tree_1 (class lto_input_block *ib, class data_in *data_in, tree expr) /* Read all the pointer fields in EXPR. */ streamer_read_tree_body (ib, data_in, expr); - /* Read any LTO-specific data not read by the tree streamer. */ + /* Read any LTO-specific data not read by the tree streamer. Do not use + stream_read_tree here since that flushes the dref_queue in mids of + SCC reading. */ if (DECL_P (expr) && TREE_CODE (expr) != FUNCTION_DECL && TREE_CODE (expr) != TRANSLATION_UNIT_DECL) - DECL_INITIAL (expr) = stream_read_tree (ib, data_in); + DECL_INITIAL (expr) + = lto_input_tree_1 (ib, data_in, streamer_read_record_start (ib), 0); /* Stream references to early generated DIEs. Keep in sync with the trees handled in dwarf2out_register_external_die. */ diff --git a/gcc/omp-expand.cc b/gcc/omp-expand.cc index 64e6308..48fbd15 100644 --- a/gcc/omp-expand.cc +++ b/gcc/omp-expand.cc @@ -8617,7 +8617,7 @@ expand_omp_atomic_load (basic_block load_bb, tree addr, basic_block store_bb; location_t loc; gimple *stmt; - tree decl, call, type, itype; + tree decl, type, itype; gsi = gsi_last_nondebug_bb (load_bb); stmt = gsi_stmt (gsi); @@ -8637,23 +8637,33 @@ expand_omp_atomic_load (basic_block load_bb, tree addr, itype = TREE_TYPE (TREE_TYPE (decl)); enum omp_memory_order omo = gimple_omp_atomic_memory_order (stmt); - tree mo = build_int_cst (NULL, omp_memory_order_to_memmodel (omo)); - call = build_call_expr_loc (loc, decl, 2, addr, mo); + tree mo = build_int_cst (integer_type_node, + omp_memory_order_to_memmodel (omo)); + gcall *call = gimple_build_call (decl, 2, addr, mo); + gimple_set_location (call, loc); + gimple_set_vuse (call, gimple_vuse (stmt)); + gimple *repl; if (!useless_type_conversion_p (type, itype)) - call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call); - call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call); - - force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT); - gsi_remove (&gsi, true); + { + tree lhs = make_ssa_name (itype); + gimple_call_set_lhs (call, lhs); + gsi_insert_before (&gsi, call, GSI_SAME_STMT); + repl = gimple_build_assign (loaded_val, + build1 (VIEW_CONVERT_EXPR, type, lhs)); + gimple_set_location (repl, loc); + } + else + { + gimple_call_set_lhs (call, loaded_val); + repl = call; + } + gsi_replace (&gsi, repl, true); store_bb = single_succ (load_bb); gsi = gsi_last_nondebug_bb (store_bb); gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE); gsi_remove (&gsi, true); - if (gimple_in_ssa_p (cfun)) - update_ssa (TODO_update_ssa_no_phi); - return true; } @@ -8669,7 +8679,7 @@ expand_omp_atomic_store (basic_block load_bb, tree addr, basic_block store_bb = single_succ (load_bb); location_t loc; gimple *stmt; - tree decl, call, type, itype; + tree decl, type, itype; machine_mode imode; bool exchange; @@ -8710,25 +8720,36 @@ expand_omp_atomic_store (basic_block load_bb, tree addr, if (!useless_type_conversion_p (itype, type)) stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val); enum omp_memory_order omo = gimple_omp_atomic_memory_order (stmt); - tree mo = build_int_cst (NULL, omp_memory_order_to_memmodel (omo)); - call = build_call_expr_loc (loc, decl, 3, addr, stored_val, mo); + tree mo = build_int_cst (integer_type_node, + omp_memory_order_to_memmodel (omo)); + stored_val = force_gimple_operand_gsi (&gsi, stored_val, true, NULL_TREE, + true, GSI_SAME_STMT); + gcall *call = gimple_build_call (decl, 3, addr, stored_val, mo); + gimple_set_location (call, loc); + gimple_set_vuse (call, gimple_vuse (stmt)); + gimple_set_vdef (call, gimple_vdef (stmt)); + + gimple *repl = call; if (exchange) { if (!useless_type_conversion_p (type, itype)) - call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call); - call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call); + { + tree lhs = make_ssa_name (itype); + gimple_call_set_lhs (call, lhs); + gsi_insert_before (&gsi, call, GSI_SAME_STMT); + repl = gimple_build_assign (loaded_val, + build1 (VIEW_CONVERT_EXPR, type, lhs)); + gimple_set_location (repl, loc); + } + else + gimple_call_set_lhs (call, loaded_val); } - - force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT); - gsi_remove (&gsi, true); + gsi_replace (&gsi, repl, true); /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */ gsi = gsi_last_nondebug_bb (load_bb); gsi_remove (&gsi, true); - if (gimple_in_ssa_p (cfun)) - update_ssa (TODO_update_ssa_no_phi); - return true; } @@ -8874,10 +8895,7 @@ expand_omp_atomic_fetch_op (basic_block load_bb, gsi_remove (&gsi, true); if (gimple_in_ssa_p (cfun)) - { - release_defs (stmt); - update_ssa (TODO_update_ssa_no_phi); - } + release_defs (stmt); return true; } @@ -9333,16 +9351,16 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb, } /* Remove GIMPLE_OMP_ATOMIC_STORE. */ + stmt = gsi_stmt (si); gsi_remove (&si, true); + if (gimple_in_ssa_p (cfun)) + release_defs (stmt); class loop *loop = alloc_loop (); loop->header = loop_header; loop->latch = store_bb; add_loop (loop, loop_header->loop_father); - if (gimple_in_ssa_p (cfun)) - update_ssa (TODO_update_ssa_no_phi); - return true; } @@ -9399,15 +9417,14 @@ expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb, gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE); stmt = gimple_build_assign (unshare_expr (mem), stored_val); + gimple_set_vuse (stmt, gimple_vuse (gsi_stmt (si))); + gimple_set_vdef (stmt, gimple_vdef (gsi_stmt (si))); gsi_insert_before (&si, stmt, GSI_SAME_STMT); t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END); t = build_call_expr (t, 0); force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT); gsi_remove (&si, true); - - if (gimple_in_ssa_p (cfun)) - update_ssa (TODO_update_ssa_no_phi); return true; } diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc index d73c165..3c4b859 100644 --- a/gcc/omp-low.cc +++ b/gcc/omp-low.cc @@ -6241,10 +6241,10 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, } if (POINTER_TYPE_P (TREE_TYPE (x))) - x = fold_build2 (POINTER_PLUS_EXPR, - TREE_TYPE (x), x, t); + x = fold_build_pointer_plus (x, t); else - x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x, t); + x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x, + fold_convert (TREE_TYPE (x), t)); } if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR diff --git a/gcc/params.opt b/gcc/params.opt index 2f9c9cf..201b5c9 100644 --- a/gcc/params.opt +++ b/gcc/params.opt @@ -498,10 +498,6 @@ The maximum number of nested indirect inlining performed by early inliner. Common Joined UInteger Var(param_max_fields_for_field_sensitive) Param Maximum number of fields in a structure before pointer analysis treats the structure as a single variable. --param=max-fsm-thread-length= -Common Joined UInteger Var(param_max_fsm_thread_length) Init(10) IntegerRange(1, 999999) Param Optimization -Maximum number of basic blocks on a jump thread path. - -param=max-fsm-thread-path-insns= Common Joined UInteger Var(param_max_fsm_thread_path_insns) Init(100) IntegerRange(1, 999999) Param Optimization Maximum number of instructions to copy when duplicating blocks on a finite state automaton jump thread path. @@ -582,6 +578,10 @@ Bound on the number of iterations the brute force # of iterations analysis algor Common Joined UInteger Var(param_max_jump_thread_duplication_stmts) Init(15) Param Optimization Maximum number of statements allowed in a block that needs to be duplicated when threading jumps. +-param=max-jump-thread-paths= +Common Joined UInteger Var(param_max_jump_thread_paths) Init(64) IntegerRange(1, 65536) Param Optimization +Search space limit for the backwards jump threader. + -param=max-last-value-rtl= Common Joined UInteger Var(param_max_last_value_rtl) Init(10000) Param Optimization The maximum number of RTL nodes that can be recorded as combiner's last value. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fee24d2..19a5303 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,40 @@ +2022-08-08 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/106556 + * gfortran.dg/pr106556.f90: New. + +2022-08-08 Tom Honermann <tom@honermann.net> + + PR preprocessor/106426 + * g++.dg/ext/char8_t-char-literal-1.C: Check signedness of u8 literals. + * g++.dg/ext/char8_t-char-literal-2.C: Check signedness of u8 literals. + +2022-08-08 Tom Honermann <tom@honermann.net> + + * gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c: New test. + * gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c: New test. + * gcc.dg/c11-utf8str-type.c: New test. + * gcc.dg/c17-utf8str-type.c: New test. + * gcc.dg/c2x-utf8str-type.c: New test. + * gcc.dg/c2x-utf8str.c: New test. + * gcc.dg/gnu2x-utf8str-type.c: New test. + * gcc.dg/gnu2x-utf8str.c: New test. + +2022-08-08 Iain Buclaw <ibuclaw@gdcproject.org> + + PR d/106555 + * gdc.dg/imports/pr106555.d: New test. + * gdc.dg/pr106555.d: New test. + +2022-08-08 Andrew Pinski <apinski@marvell.com> + + * gcc.dg/pr87052.c: Update d var to expect nothing. + +2022-08-08 Andrew Pinski <apinski@marvell.com> + + * gcc.dg/tree-ssa/pr93776.c: Moved to... + * gcc.c-torture/compile/pr93776.c: ...here. + 2022-08-07 Roger Sayle <roger@nextmovesoftware.com> * gcc.target/i386/cmpti2.c: Add -mno-stv to dg-options. diff --git a/gcc/testsuite/g++.dg/ext/char8_t-char-literal-1.C b/gcc/testsuite/g++.dg/ext/char8_t-char-literal-1.C index 8ed85cc..2994dd3 100644 --- a/gcc/testsuite/g++.dg/ext/char8_t-char-literal-1.C +++ b/gcc/testsuite/g++.dg/ext/char8_t-char-literal-1.C @@ -1,6 +1,6 @@ // Test that UTF-8 character literals have type char if -fchar8_t is not enabled. // { dg-do compile } -// { dg-options "-std=c++17 -fno-char8_t" } +// { dg-options "-std=c++17 -fsigned-char -fno-char8_t" } template<typename T1, typename T2> struct is_same @@ -10,3 +10,7 @@ template<typename T> { static const bool value = true; }; static_assert(is_same<decltype(u8'x'), char>::value, "Error"); + +#if u8'\0' - 1 > 0 +#error "UTF-8 character literals not signed in preprocessor" +#endif diff --git a/gcc/testsuite/g++.dg/ext/char8_t-char-literal-2.C b/gcc/testsuite/g++.dg/ext/char8_t-char-literal-2.C index 7861736..db4fe70 100644 --- a/gcc/testsuite/g++.dg/ext/char8_t-char-literal-2.C +++ b/gcc/testsuite/g++.dg/ext/char8_t-char-literal-2.C @@ -10,3 +10,7 @@ template<typename T> { static const bool value = true; }; static_assert(is_same<decltype(u8'x'), char8_t>::value, "Error"); + +#if u8'\0' - 1 < 0 +#error "UTF-8 character literals not unsigned in preprocessor" +#endif diff --git a/gcc/testsuite/g++.dg/gomp/pr106492.C b/gcc/testsuite/g++.dg/gomp/pr106492.C new file mode 100644 index 0000000..f263bb4 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/pr106492.C @@ -0,0 +1,49 @@ +/* PR middle-end/106492 */ + +template <typename T> +struct S { + T a : 12; + S () : a(0) + { +#pragma omp for simd linear(a) + for (int k = 0; k < 64; ++k) + a++; + } +}; +struct U { + int a : 12; + U () : a(0) + { +#pragma omp for simd linear(a) + for (int k = 0; k < 64; ++k) + a++; + } +}; + +S<int> s; +U u; + + +template <typename T> +struct Sptr { + T a; + Sptr (T init) : a(init) + { +#pragma omp for simd linear(a) + for (int k = 0; k < 64; ++k) + a++; + } +}; +struct Uptr { + int *a; + Uptr (int *init) : a(init) + { +#pragma omp for simd linear(a) + for (int k = 0; k < 64; ++k) + a++; + } +}; + +int i[1024]; +Sptr<int *> sptr(i); +Uptr uptr(&i[100]); diff --git a/gcc/testsuite/gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c b/gcc/testsuite/gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c new file mode 100644 index 0000000..1b692f5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c @@ -0,0 +1,42 @@ +/* Test atomic_is_lock_free for char8_t. */ +/* { dg-do run } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +#include <stdatomic.h> +#include <stdint.h> + +extern void abort (void); + +_Atomic __CHAR8_TYPE__ ac8a; +atomic_char8_t ac8t; + +#define CHECK_TYPE(MACRO, V1, V2) \ + do \ + { \ + int r1 = MACRO; \ + int r2 = atomic_is_lock_free (&V1); \ + int r3 = atomic_is_lock_free (&V2); \ + if (r1 != 0 && r1 != 1 && r1 != 2) \ + abort (); \ + if (r2 != 0 && r2 != 1) \ + abort (); \ + if (r3 != 0 && r3 != 1) \ + abort (); \ + if (r1 == 2 && r2 != 1) \ + abort (); \ + if (r1 == 2 && r3 != 1) \ + abort (); \ + if (r1 == 0 && r2 != 0) \ + abort (); \ + if (r1 == 0 && r3 != 0) \ + abort (); \ + } \ + while (0) + +int +main () +{ + CHECK_TYPE (ATOMIC_CHAR8_T_LOCK_FREE, ac8a, ac8t); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c b/gcc/testsuite/gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c new file mode 100644 index 0000000..27a3cfe --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c @@ -0,0 +1,5 @@ +/* Test atomic_is_lock_free for char8_t with -std=gnu2x. */ +/* { dg-do run } */ +/* { dg-options "-std=gnu2x -pedantic-errors" } */ + +#include "c2x-stdatomic-lockfree-char8_t.c" diff --git a/gcc/testsuite/gcc.dg/c11-utf8str-type.c b/gcc/testsuite/gcc.dg/c11-utf8str-type.c new file mode 100644 index 0000000..8be9abb --- /dev/null +++ b/gcc/testsuite/gcc.dg/c11-utf8str-type.c @@ -0,0 +1,6 @@ +/* Test C11 UTF-8 string literal type. */ +/* { dg-do compile } */ +/* { dg-options "-std=c11" } */ + +_Static_assert (_Generic (u8"text", char*: 1, default: 2) == 1, "UTF-8 string literals have an unexpected type"); +_Static_assert (_Generic (u8"x"[0], char: 1, default: 2) == 1, "UTF-8 string literal elements have an unexpected type"); diff --git a/gcc/testsuite/gcc.dg/c17-utf8str-type.c b/gcc/testsuite/gcc.dg/c17-utf8str-type.c new file mode 100644 index 0000000..515c6db --- /dev/null +++ b/gcc/testsuite/gcc.dg/c17-utf8str-type.c @@ -0,0 +1,6 @@ +/* Test C17 UTF-8 string literal type. */ +/* { dg-do compile } */ +/* { dg-options "-std=c17" } */ + +_Static_assert (_Generic (u8"text", char*: 1, default: 2) == 1, "UTF-8 string literals have an unexpected type"); +_Static_assert (_Generic (u8"x"[0], char: 1, default: 2) == 1, "UTF-8 string literal elements have an unexpected type"); diff --git a/gcc/testsuite/gcc.dg/c2x-utf8str-type.c b/gcc/testsuite/gcc.dg/c2x-utf8str-type.c new file mode 100644 index 0000000..ebdde97 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-utf8str-type.c @@ -0,0 +1,6 @@ +/* Test C2X UTF-8 string literal type. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x" } */ + +_Static_assert (_Generic (u8"text", unsigned char*: 1, default: 2) == 1, "UTF-8 string literals have an unexpected type"); +_Static_assert (_Generic (u8"x"[0], unsigned char: 1, default: 2) == 1, "UTF-8 string literal elements have an unexpected type"); diff --git a/gcc/testsuite/gcc.dg/c2x-utf8str.c b/gcc/testsuite/gcc.dg/c2x-utf8str.c new file mode 100644 index 0000000..2e4c392 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-utf8str.c @@ -0,0 +1,34 @@ +/* Test initialization by UTF-8 string literal in C2X. */ +/* { dg-do compile } */ +/* { dg-require-effective-target wchar } */ +/* { dg-options "-std=c2x" } */ + +typedef __CHAR8_TYPE__ char8_t; +typedef __CHAR16_TYPE__ char16_t; +typedef __CHAR32_TYPE__ char32_t; +typedef __WCHAR_TYPE__ wchar_t; + +/* Test that char, signed char, unsigned char, and char8_t arrays can be + initialized by a UTF-8 string literal. */ +const char cbuf1[] = u8"text"; +const char cbuf2[] = { u8"text" }; +const signed char scbuf1[] = u8"text"; +const signed char scbuf2[] = { u8"text" }; +const unsigned char ucbuf1[] = u8"text"; +const unsigned char ucbuf2[] = { u8"text" }; +const char8_t c8buf1[] = u8"text"; +const char8_t c8buf2[] = { u8"text" }; + +/* Test that a diagnostic is issued for attempted initialization of + other character types by a UTF-8 string literal. */ +const char16_t c16buf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */ +const char16_t c16buf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */ +const char32_t c32buf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */ +const char32_t c32buf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */ +const wchar_t wbuf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */ +const wchar_t wbuf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */ + +/* Test that char8_t arrays can be initialized by an ordinary string + literal. */ +const char8_t c8buf3[] = "text"; +const char8_t c8buf4[] = { "text" }; diff --git a/gcc/testsuite/gcc.dg/gnu2x-utf8str-type.c b/gcc/testsuite/gcc.dg/gnu2x-utf8str-type.c new file mode 100644 index 0000000..efe16ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/gnu2x-utf8str-type.c @@ -0,0 +1,5 @@ +/* Test C2X UTF-8 string literal type with -std=gnu2x. */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu2x" } */ + +#include "c2x-utf8str-type.c" diff --git a/gcc/testsuite/gcc.dg/gnu2x-utf8str.c b/gcc/testsuite/gcc.dg/gnu2x-utf8str.c new file mode 100644 index 0000000..f3719ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/gnu2x-utf8str.c @@ -0,0 +1,34 @@ +/* Test initialization by UTF-8 string literal in C2X with -std=gnu2x. */ +/* { dg-do compile } */ +/* { dg-require-effective-target wchar } */ +/* { dg-options "-std=gnu2x" } */ + +typedef __CHAR8_TYPE__ char8_t; +typedef __CHAR16_TYPE__ char16_t; +typedef __CHAR32_TYPE__ char32_t; +typedef __WCHAR_TYPE__ wchar_t; + +/* Test that char, signed char, unsigned char, and char8_t arrays can be + initialized by a UTF-8 string literal. */ +const char cbuf1[] = u8"text"; +const char cbuf2[] = { u8"text" }; +const signed char scbuf1[] = u8"text"; +const signed char scbuf2[] = { u8"text" }; +const unsigned char ucbuf1[] = u8"text"; +const unsigned char ucbuf2[] = { u8"text" }; +const char8_t c8buf1[] = u8"text"; +const char8_t c8buf2[] = { u8"text" }; + +/* Test that a diagnostic is issued for attempted initialization of + other character types by a UTF-8 string literal. */ +const char16_t c16buf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */ +const char16_t c16buf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */ +const char32_t c32buf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */ +const char32_t c32buf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */ +const wchar_t wbuf1[] = u8"text"; /* { dg-error "from a string literal with type array of .unsigned char." } */ +const wchar_t wbuf2[] = { u8"text" }; /* { dg-error "from a string literal with type array of .unsigned char." } */ + +/* Test that char8_t arrays can be initialized by an ordinary string + literal. */ +const char8_t c8buf3[] = "text"; +const char8_t c8buf4[] = { "text" }; diff --git a/gcc/testsuite/gcc.dg/pr87052.c b/gcc/testsuite/gcc.dg/pr87052.c index 18e092c..796fe64 100644 --- a/gcc/testsuite/gcc.dg/pr87052.c +++ b/gcc/testsuite/gcc.dg/pr87052.c @@ -23,8 +23,7 @@ void test (void) const char d[0] = { }; - /* Expect the following: - d = ""; */ + /* Expect nothing. */ const char e[0] = ""; @@ -36,6 +35,7 @@ void test (void) /* { dg-final { scan-tree-dump-times "a = \"\\\\x00ab\";" 1 "gimple" } } { dg-final { scan-tree-dump-times "b = \"a\\\\x00bc\";" 1 "gimple" } } { dg-final { scan-tree-dump-times "c = \"\";" 1 "gimple" } } - { dg-final { scan-tree-dump-times "d = { *};" 1 "gimple" } } + { dg-final { scan-tree-dump-times "d = " 1 "gimple" } } + { dg-final { scan-tree-dump-times "d = {CLOBBER\\(eol\\)}" 1 "gimple" } } { dg-final { scan-tree-dump-times "e = " 1 "gimple" } } { dg-final { scan-tree-dump-times "e = {CLOBBER\\(eol\\)}" 1 "gimple" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c index aa06db5..47b8fdf 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c @@ -11,7 +11,7 @@ to change decisions in switch expansion which in turn can expose new jump threading opportunities. Skip the later tests on aarch64. */ /* { dg-final { scan-tree-dump-not "Jumps threaded" "dom3" { target { ! aarch64*-*-* } } } } */ -/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread2" { target { ! aarch64*-*-* } } } } */ +/* { dg-final { scan-tree-dump "Jumps threaded: 9" "thread2" { target { ! aarch64*-*-* } } } } */ /* { dg-final { scan-tree-dump "Jumps threaded: 18" "thread2" { target { aarch64*-*-* } } } } */ enum STATE { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-16.c new file mode 100644 index 0000000..f96170b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-16.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-threadfull1-details" } */ + +int res; +void foo (int a, int b, int c, int d, int e) +{ + if (a > 100) + res = 3; + if (b != 5) + res = 5; + if (c == 29) + res = 7; + if (d < 2) + res = 9; + /* Accounting whoes makes this not catched. */ +#if 0 + if (e != 37) + res = 11; +#endif + if (a < 10) + res = 13; +} + +/* { dg-final { scan-tree-dump "SUCCESS" "threadfull1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-17.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-17.c new file mode 100644 index 0000000..94ee666 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-17.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-threadfull1-details --param max-jump-thread-paths=15" } */ + +#include "ssa-thread-16.c" + +/* With limiting the search space we should no longer consider this path. */ +/* { dg-final { scan-tree-dump-not "SUCCESS" "threadfull1" } } */ diff --git a/gcc/testsuite/gdc.dg/imports/pr106555.d b/gcc/testsuite/gdc.dg/imports/pr106555.d new file mode 100644 index 0000000..0d3ab6b --- /dev/null +++ b/gcc/testsuite/gdc.dg/imports/pr106555.d @@ -0,0 +1,10 @@ +module imports.pr106555; +struct S106555 +{ + int[] f106555; + int max106555; + this(int) + { + f106555.length = max106555; + } +} diff --git a/gcc/testsuite/gdc.dg/pr106555.d b/gcc/testsuite/gdc.dg/pr106555.d new file mode 100644 index 0000000..7b40f3c --- /dev/null +++ b/gcc/testsuite/gdc.dg/pr106555.d @@ -0,0 +1,4 @@ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106555 +// { dg-do compile } +// { dg-additional-options "-O2" } +// { dg-additional-sources "imports/pr106555.d" } diff --git a/gcc/testsuite/gdc.dg/torture/imports/pr106563math.d b/gcc/testsuite/gdc.dg/torture/imports/pr106563math.d new file mode 100644 index 0000000..b9351ea --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/imports/pr106563math.d @@ -0,0 +1,12 @@ +module imports.pr106563math; + +T nextPow2(T)(const T val) +{ + return powIntegralImpl(val); +} + +pragma(inline, true) +T powIntegralImpl(T)(T) +{ + return 1; +} diff --git a/gcc/testsuite/gdc.dg/torture/imports/pr106563regex.d b/gcc/testsuite/gdc.dg/torture/imports/pr106563regex.d new file mode 100644 index 0000000..a2cd90c --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/imports/pr106563regex.d @@ -0,0 +1,7 @@ +module imports.pr106563regex; +import imports.pr106563uni; + +struct CharMatcher +{ + typeof(MultiArray!().length) trie; +} diff --git a/gcc/testsuite/gdc.dg/torture/imports/pr106563uni.d b/gcc/testsuite/gdc.dg/torture/imports/pr106563uni.d new file mode 100644 index 0000000..16e3bc8 --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/imports/pr106563uni.d @@ -0,0 +1,15 @@ +module imports.pr106563uni; + +struct MultiArray() +{ + @property length() + { + return spaceFor!0(); + } +} + +size_t spaceFor(size_t bits)() +{ + import imports.pr106563math; + return nextPow2(bits); +} diff --git a/gcc/testsuite/gdc.dg/torture/pr106563.d b/gcc/testsuite/gdc.dg/torture/pr106563.d new file mode 100644 index 0000000..7e15442 --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/pr106563.d @@ -0,0 +1,16 @@ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106563 +// { dg-do link } +// { dg-additional-files "imports/pr106563math.d imports/pr106563regex.d imports/pr106563uni.d" } +// { dg-additional-options "-I[srcdir] -fno-druntime" } +import imports.pr106563math; +import imports.pr106563regex; + +auto requireSize()(size_t size) +{ + return nextPow2(size); +} + +extern(C) int main() +{ + return cast(int)requireSize(0); +} diff --git a/gcc/testsuite/gdc.dg/torture/torture.exp b/gcc/testsuite/gdc.dg/torture/torture.exp index f7d00b1..d9c6a79 100644 --- a/gcc/testsuite/gdc.dg/torture/torture.exp +++ b/gcc/testsuite/gdc.dg/torture/torture.exp @@ -19,6 +19,15 @@ # Load support procs. load_lib gdc-dg.exp +# Helper function allows adding tests that use imports/*, but don't compile +# the sources in with dg-additional-sources. +global testdir +set testdir $srcdir/$subdir +proc srcdir {} { + global testdir + return $testdir +} + # The default option list can be overridden by # TORTURE_OPTIONS="{ { list1 } ... { listN } }" diff --git a/gcc/testsuite/gfortran.dg/pr106556.f90 b/gcc/testsuite/gfortran.dg/pr106556.f90 new file mode 100644 index 0000000..01b89a8 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr106556.f90 @@ -0,0 +1,10 @@ +! { dg-do compile } +! { dg-options "-O1 -fnon-call-exceptions -ftree-loop-if-convert" } + + +program p + real :: a(2) + + a(:) = 1.0 + if (minloc (a, dim = 1).ne.1) STOP 1 +end diff --git a/gcc/tree-parloops.cc b/gcc/tree-parloops.cc index 2d3aa78..b070527 100644 --- a/gcc/tree-parloops.cc +++ b/gcc/tree-parloops.cc @@ -3082,7 +3082,7 @@ gen_parallel_loop (class loop *loop, profile_probability::unlikely (), profile_probability::likely (), profile_probability::unlikely (), true); - update_ssa (TODO_update_ssa); + update_ssa (TODO_update_ssa_no_phi); free_original_copy_tables (); } diff --git a/gcc/tree-ssa-threadbackward.cc b/gcc/tree-ssa-threadbackward.cc index 332a1d2..30047c6 100644 --- a/gcc/tree-ssa-threadbackward.cc +++ b/gcc/tree-ssa-threadbackward.cc @@ -90,7 +90,7 @@ private: bool debug_counter (); edge maybe_register_path (); void maybe_register_path_dump (edge taken_edge); - void find_paths_to_names (basic_block bb, bitmap imports); + void find_paths_to_names (basic_block bb, bitmap imports, unsigned); edge find_taken_edge (const vec<basic_block> &path); edge find_taken_edge_cond (const vec<basic_block> &path, gcond *); edge find_taken_edge_switch (const vec<basic_block> &path, gswitch *); @@ -337,9 +337,12 @@ back_threader::find_taken_edge_cond (const vec<basic_block> &path, // INTERESTING bitmap, and register any such paths. // // BB is the current path being processed. +// +// OVERALL_PATHS is the search space up to this block void -back_threader::find_paths_to_names (basic_block bb, bitmap interesting) +back_threader::find_paths_to_names (basic_block bb, bitmap interesting, + unsigned overall_paths) { if (m_visited_bbs.add (bb)) return; @@ -352,8 +355,10 @@ back_threader::find_paths_to_names (basic_block bb, bitmap interesting) || maybe_register_path ())) ; - // Continue looking for ways to extend the path - else + // Continue looking for ways to extend the path but limit the + // search space along a branch + else if ((overall_paths = overall_paths * EDGE_COUNT (bb->preds)) + <= (unsigned)param_max_jump_thread_paths) { // For further greedy searching we want to remove interesting // names defined in BB but add ones on the PHI edges for the @@ -407,7 +412,7 @@ back_threader::find_paths_to_names (basic_block bb, bitmap interesting) unwind.quick_push (def); } } - find_paths_to_names (e->src, new_interesting); + find_paths_to_names (e->src, new_interesting, overall_paths); // Restore new_interesting. We leave m_imports alone since // we do not prune defs in BB from it and separately keeping // track of which bits to unwind isn't worth the trouble. @@ -417,6 +422,9 @@ back_threader::find_paths_to_names (basic_block bb, bitmap interesting) } } } + else if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " FAIL: Search space limit %d reached.\n", + param_max_jump_thread_paths); // Reset things to their original state. m_path.pop (); @@ -447,7 +455,7 @@ back_threader::find_paths (basic_block bb, tree name) auto_bitmap interesting; bitmap_copy (interesting, m_imports); - find_paths_to_names (bb, interesting); + find_paths_to_names (bb, interesting, 1); } } @@ -561,15 +569,6 @@ back_threader_profitability::profitable_path_p (const vec<basic_block> &m_path, if (m_path.length () <= 1) return false; - if (m_path.length () > (unsigned) param_max_fsm_thread_length) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " FAIL: Jump-thread path not considered: " - "the number of basic blocks on the path " - "exceeds PARAM_MAX_FSM_THREAD_LENGTH.\n"); - return false; - } - int n_insns = 0; gimple_stmt_iterator gsi; loop_p loop = m_path[0]->loop_father; |