diff options
Diffstat (limited to 'gcc')
156 files changed, 2702 insertions, 838 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9a69cec..e4c9846 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,170 @@ +2025-06-19 Jakub Jelinek <jakub@redhat.com> + + PR target/120689 + * function.cc (assign_parm_setup_block): Align parm to at least + word alignment even on !STRICT_ALIGNMENT targets, as long as + BITS_PER_WORD is not larger than MAX_SUPPORTED_STACK_ALIGNMENT. + +2025-06-19 H.J. Lu <hjl.tools@gmail.com> + + PR target/120427 + * config/i386/i386.md (*mov<mode>_and): Changed to + define_insn_and_split. Split it to "mov $0,mem" if not -Oz. + (*mov<mode>_or): Changed to define_insn_and_split. Split it + to "mov $-1,mem" if not -Oz. + (peephole2): Don't transform "mov $-1,reg" to "push $-1; pop reg" + for -Oz since it will be transformed to "or $-1,reg". + +2025-06-19 Georg-Johann Lay <avr@gjlay.de> + + PR other/115893 + * doc/install.texi (Prerequisites): Note that Texinfo older + than v7.1 may throw incorrect build warnings, cf. + https://lists.nongnu.org/archive/html/help-texinfo/2023-11/msg00004.html + +2025-06-19 Dongyan Chen <chendongyan@isrc.iscas.ac.cn> + + * config/riscv/riscv-cores.def (RISCV_TUNE): Add "generic" tune. + * config/riscv/riscv.cc: Add generic_tune_info. + * config/riscv/riscv.h (RISCV_TUNE_STRING_DEFAULT): Change default tune. + +2025-06-19 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/120631 + * dfp.cc (decimal_real_to_integer): Use result multiplication not just + when precision > 128 and dn.exponent > 19, but when precision > 64 + and dn.exponent > 0. + +2025-06-19 Kito Cheng <kito.cheng@sifive.com> + + * config/riscv/riscv.cc (riscv_legitimize_move): Use + riscv_2x_xlen_mode_p. + (riscv_binary_cost): Ditto. + (riscv_hard_regno_mode_ok): Ditto. + +2025-06-19 Kito Cheng <kito.cheng@sifive.com> + + * config/riscv/riscv.cc (riscv_cost_model): Add cost model for + zilsd. + +2025-06-19 Lili Cui <lili.cui@intel.com> + + PR target/120697 + * config/i386/i386.cc (ix86_expand_prologue): + Remove 3 assertions and associated code. + +2025-06-18 Dimitar Dimitrov <dimitar@dinux.eu> + Richard Sandiford <richard.sandiford@arm.com> + Andrew Pinski <quic_apinski@quicinc.com> + + PR target/119966 + * emit-rtl.cc (validate_subreg): Call simplify_subreg_regno + instead of checking info.representable_p.. + * rtl.h (simplify_subreg_regno): Add new argument + allow_stack_regs. + * rtlanal.cc (simplify_subreg_regno): Do not reject + stack-related registers if allow_stack_regs is true. + +2025-06-18 Andrew MacLeod <amacleod@redhat.com> + + * value-range.cc (irange::intersect_bitmask): Always update the + stored mask to reflect the current calculated mask. + +2025-06-18 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/119039 + * value-range.cc (irange::contains_p): Call wide_int version of + contains_p for singleton ranges. + (irange::intersect): If either range is a singleton, use + contains_p. + +2025-06-18 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/119039 + * vr-values.cc (simplify_using_ranges::legacy_fold_cond): Remove. + (simplify_using_ranges::simplify_switch_using_ranges): Adjust. + +2025-06-18 Richard Biener <rguenther@suse.de> + + * tree-cfg.cc (dump_function_to_file): Use flags, not dump_flags. + +2025-06-18 Jan Beulich <jbeulich@suse.com> + + * doc/gcov.texi: Drop blank after @anchor. + +2025-06-18 Jan Beulich <jbeulich@suse.com> + + * doc/extend.texi: Fill first argument of @xref{}. + +2025-06-18 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/120631 + * real.cc (decimal_from_integer): Add digits argument, if larger than + 256, use XALLOCAVEC allocated buffer. + (real_from_integer): Pass val_in's precision divided by 3 to + decimal_from_integer. + * dfp.cc (decimal_real_to_integer): For precision > 128 if finite + and exponent is large, decrease exponent and multiply resulting + wide_int by powers of 10^19. + +2025-06-18 Pan Li <pan2.li@intel.com> + + * config/riscv/riscv-v.cc (expand_vx_binary_vec_dup_vec): Add + new case SMIN. + (expand_vx_binary_vec_vec_dup): Ditto. + * config/riscv/riscv.cc (riscv_rtx_costs): Ditto. + * config/riscv/vector-iterators.md: Add new op smin. + +2025-06-18 Lili Cui <lili.cui@intel.com> + Michael Matz <matz@suse.de> + + * config/i386/i386-protos.h (ix86_get_separate_components): + New function. + (ix86_components_for_bb): Likewise. + (ix86_disqualify_components): Likewise. + (ix86_emit_prologue_components): Likewise. + (ix86_emit_epilogue_components): Likewise. + (ix86_set_handled_components): Likewise. + * config/i386/i386.cc (save_regs_using_push_pop): + Split from ix86_compute_frame_layout. + (ix86_compute_frame_layout): + Use save_regs_using_push_pop. + (pro_epilogue_adjust_stack): + Use gen_pro_epilogue_adjust_stack_add_nocc. + (ix86_expand_prologue): Add some assertions and adjust + the stack frame at the beginning of the prolog for shrink + wrapping separate. + (ix86_emit_save_regs_using_mov): + Skip registers that are wrapped separately. + (ix86_emit_restore_regs_using_mov): Likewise. + (ix86_expand_epilogue): Add some assertions and set + restore_regs_via_mov to true for shrink wrapping separate. + (ix86_get_separate_components): New function. + (ix86_components_for_bb): Likewise. + (ix86_disqualify_components): Likewise. + (ix86_emit_prologue_components): Likewise. + (ix86_emit_epilogue_components): Likewise. + (ix86_set_handled_components): Likewise. + (TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS): Define. + (TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB): Likewise. + (TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS): Likewise. + (TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS): Likewise. + (TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS): Likewise. + (TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS): Likewise. + * config/i386/i386.h (struct machine_function):Add + reg_is_wrapped_separately array for register wrapping + information. + * config/i386/i386.md + (@pro_epilogue_adjust_stack_add_nocc<mode>): New. + +2025-06-18 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/120661 + * value-range.cc (irange::snap): New. + (irange::snap_subranges): New. + (irange::set_range_from_bitmask): Call snap_subranges. + * value-range.h (snap, snap_subranges): New prototypes. + 2025-06-17 Jan Hubicka <hubicka@ucw.cz> * auto-profile.cc (afdo_indirect_call): Compute speculative edge diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 016543e..48356de 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20250618 +20250620 diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index 1fbba5d..cc86675 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,20 @@ +2025-06-18 David Malcolm <dmalcolm@redhat.com> + + * checker-event.h (checker_event::get_kind): New accessor. + (checker_event::m_kind): Make private. + * checker-path.cc (checker_path::maybe_log): Use accessor for + checker_event::m_kind. + (checker_path::add_event): Likewise. + (checker_path::debug): Likewise. + (checker_path::cfg_edge_pair_at_p): Likewise. + (checker_path::inject_any_inlined_call_events): Likewise. + * diagnostic-manager.cc + (diagnostic_manager::prune_for_sm_diagnostic): Likewise. + (diagnostic_manager::prune_for_sm_diagnostic): Likewise. + (diagnostic_manager::consolidate_conditions): Likewise. + (diagnostic_manager::consolidate_unwind_events): Likewise. + (diagnostic_manager::finish_pruning): Likewise. + 2025-05-06 David Malcolm <dmalcolm@redhat.com> * checker-event.cc (checker_event::checker_event): Update diff --git a/gcc/analyzer/checker-event.h b/gcc/analyzer/checker-event.h index 2f26b8d..e29173a 100644 --- a/gcc/analyzer/checker-event.h +++ b/gcc/analyzer/checker-event.h @@ -116,6 +116,7 @@ public: sarif_object &thread_flow_loc_obj) const override; /* Additional functionality. */ + enum event_kind get_kind () const { return m_kind; } tree get_fndecl () const { return m_effective_fndecl; } int get_original_stack_depth () const { return m_original_depth; } @@ -142,7 +143,7 @@ protected: checker_event (enum event_kind kind, const event_loc_info &loc_info); - public: + private: const enum event_kind m_kind; protected: location_t m_loc; diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc index 9bde6f2..45593e0 100644 --- a/gcc/analyzer/checker-path.cc +++ b/gcc/analyzer/checker-path.cc @@ -89,7 +89,7 @@ checker_path::maybe_log (logger *logger, const char *desc) const { logger->start_log_line (); logger->log_partial ("%s[%i]: %s ", desc, i, - event_kind_to_string (m_events[i]->m_kind)); + event_kind_to_string (m_events[i]->get_kind ())); m_events[i]->dump (logger->get_printer ()); logger->end_log_line (); } @@ -103,7 +103,7 @@ checker_path::add_event (std::unique_ptr<checker_event> event) m_logger->start_log_line (); m_logger->log_partial ("added event[%i]: %s ", m_events.length (), - event_kind_to_string (event.get ()->m_kind)); + event_kind_to_string (event.get ()->get_kind ())); event.get ()->dump (m_logger->get_printer ()); m_logger->end_log_line (); } @@ -123,7 +123,7 @@ checker_path::debug () const fprintf (stderr, "[%i]: %s \"%s\"\n", i, - event_kind_to_string (m_events[i]->m_kind), + event_kind_to_string (m_events[i]->get_kind ()), event_desc.get ()); } } @@ -167,8 +167,8 @@ checker_path::cfg_edge_pair_at_p (unsigned idx) const { if (m_events.length () < idx + 1) return false; - return (m_events[idx]->m_kind == event_kind::start_cfg_edge - && m_events[idx + 1]->m_kind == event_kind::end_cfg_edge); + return (m_events[idx]->get_kind () == event_kind::start_cfg_edge + && m_events[idx + 1]->get_kind () == event_kind::end_cfg_edge); } /* Consider a call from "outer" to "middle" which calls "inner", @@ -254,7 +254,7 @@ checker_path::inject_any_inlined_call_events (logger *logger) { logger->start_log_line (); logger->log_partial ("event[%i]: %s ", ev_idx, - event_kind_to_string (curr_event->m_kind)); + event_kind_to_string (curr_event->get_kind ())); curr_event->dump (logger->get_printer ()); logger->end_log_line (); for (inlining_iterator iter (curr_event->get_location ()); diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc index e5d1a25..6867dd2 100644 --- a/gcc/analyzer/diagnostic-manager.cc +++ b/gcc/analyzer/diagnostic-manager.cc @@ -2599,19 +2599,19 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path, { label_text sval_desc = sval->get_desc (); log ("considering event %i (%s), with sval: %qs, state: %qs", - idx, event_kind_to_string (base_event->m_kind), + idx, event_kind_to_string (base_event->get_kind ()), sval_desc.get (), state->get_name ()); } else log ("considering event %i (%s), with global state: %qs", - idx, event_kind_to_string (base_event->m_kind), + idx, event_kind_to_string (base_event->get_kind ()), state->get_name ()); } else log ("considering event %i", idx); } - switch (base_event->m_kind) + switch (base_event->get_kind ()) { default: gcc_unreachable (); @@ -2718,7 +2718,7 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path, log ("filtering events %i and %i: CFG edge", idx, idx + 1); path->delete_event (idx); /* Also delete the corresponding event_kind::end_cfg_edge. */ - gcc_assert (path->get_checker_event (idx)->m_kind + gcc_assert (path->get_checker_event (idx)->get_kind () == event_kind::end_cfg_edge); path->delete_event (idx); } @@ -3109,7 +3109,7 @@ diagnostic_manager::consolidate_conditions (checker_path *path) const continue; /* Are we looking for a run of all TRUE edges, or all FALSE edges? */ - gcc_assert (old_start_ev->m_kind == event_kind::start_cfg_edge); + gcc_assert (old_start_ev->get_kind () == event_kind::start_cfg_edge); const start_cfg_edge_event *old_start_cfg_ev = (const start_cfg_edge_event *)old_start_ev; const cfg_superedge& first_cfg_sedge @@ -3132,7 +3132,7 @@ diagnostic_manager::consolidate_conditions (checker_path *path) const { const checker_event *iter_ev = path->get_checker_event (next_idx); - gcc_assert (iter_ev->m_kind == event_kind::start_cfg_edge); + gcc_assert (iter_ev->get_kind () == event_kind::start_cfg_edge); const start_cfg_edge_event *iter_cfg_ev = (const start_cfg_edge_event *)iter_ev; const cfg_superedge& iter_cfg_sedge @@ -3190,11 +3190,13 @@ diagnostic_manager::consolidate_unwind_events (checker_path *path) const start_idx++) { /* Find a run of consecutive unwind_event instances. */ - if (path->get_checker_event (start_idx)->m_kind != event_kind::unwind) + if (path->get_checker_event (start_idx)->get_kind () + != event_kind::unwind) continue; int iter_idx = start_idx + 1; while (iter_idx < (int)path->num_events ()) - if (path->get_checker_event (iter_idx)->m_kind == event_kind::unwind) + if (path->get_checker_event (iter_idx)->get_kind () + == event_kind::unwind) ++iter_idx; else break; @@ -3232,7 +3234,7 @@ diagnostic_manager::finish_pruning (checker_path *path) const while (idx >= 0 && idx < (signed)path->num_events ()) { checker_event *base_event = path->get_checker_event (idx); - if (base_event->m_kind == event_kind::function_entry) + if (base_event->get_kind () == event_kind::function_entry) { log ("filtering event %i:" " function entry for purely intraprocedural path", idx); diff --git a/gcc/cobol/ChangeLog b/gcc/cobol/ChangeLog index bb8d631..3ff4700 100644 --- a/gcc/cobol/ChangeLog +++ b/gcc/cobol/ChangeLog @@ -1,3 +1,103 @@ +2025-06-18 James K. Lowden <jklowden@cobolworx.com> + + PR cobol/120621 + * cbldiag.h (yyerror): Add diagnostic attributes. + (yywarn): Same. + (error_msg): Same. + (yyerrorvl): Same. + (cbl_unimplementedw): Same. + (cbl_unimplemented): Same. + (cbl_unimplemented_at): Same. + * cdf-copy.cc (copybook_elem_t::open_file): Supply string argument. + * cdf.y: Use %<%>. + * cobol-system.h (if): Check GCC_VERSION. + (ATTRIBUTE_GCOBOL_DIAG): Define. + * except.cc (cbl_enabled_exception_t::dump): Remove extra %s. + * genapi.cc (get_class_condition_string): Use acceptable message. + (get_bytes_needed): Same. + (move_tree): Same. + (get_string_from): Same. + (internal_perform_through): Same. + (tree_type_from_field_type): Same. + (is_valuable): Same. + (parser_logop): Same. + (parser_relop): Same. + (parser_relop_long): Same. + (parser_if): Same. + (parser_setop): Same. + (parser_perform_conditional): Same. + (parser_file_add): Same. + (parser_file_open): Same. + (parser_file_close): Same. + (parser_file_read): Same. + (parser_file_write): Same. + (inspect_replacing): Same. + (parser_sort): Same. + (parser_file_sort): Same. + (parser_file_merge): Same. + (create_and_call): Same. + (parser_bitop): Same. + (parser_bitwise_op): Same. + (hijack_for_development): Same. + (mh_source_is_literalN): Same. + (mh_dest_is_float): Same. + (parser_symbol_add): Same. + * gengen.cc (show_type): Use acceptable message. + (gg_find_field_in_struct): Same. + (gg_declare_variable): Same. + (gg_printf): Same. + (gg_fprintf): Same. + (gg_tack_on_function_parameters): Same. + (gg_define_function): Same. + (gg_get_function_decl): Same. + (gg_finalize_function): Same. + (gg_call_expr): Same. + (gg_call): Same. + (gg_insert_into_assembler): Define new function. + (gg_insert_into_assemblerf): Use gg_insert_into_assembler(). + * gengen.h (gg_insert_into_assembler): Simpler function declaration. + (gg_insert_into_assemblerf): Declare new function. + * genmath.cc (parser_op): Use acceptable message. + * genutil.cc (get_binary_value): Use acceptable message. + * lexio.cc (parse_replacing_pair): Correct diagnostic arguments. + (preprocess_filter_add): Same. + (cdftext::open_input): Same. + * parse.y: Use acceptable messages. + * parse_ante.h (struct evaluate_elem_t): Use %<%>. + (is_callable): Same. + * parse_util.h (intrinsic_invalid_parameter): Use %qs. + * scan.l: Use dialect_error(). + * scan_ante.h (numstr_of): Use %qs. + (scanner_token): Quote COBOL tokens in messages. + (scanner_parsing): Correct diagnostic message. + (scanner_parsing_toggle): Quote COBOL tokens in messages. + (scanner_parsing_pop): Same. + (typed_name): Use %qs. + * scan_post.h (prelex): Quote COBOL tokens in message. + * show_parse.h (CHECK_FIELD): Use acceptable message format. + (CHECK_LABEL): Same. + * symbols.cc (symbol_field_same_as): Remove extra spaces. + (cbl_alphabet_t::assign): Use %<%>. + (cbl_field_t::internalize): Quote library name in message. + * symbols.h (struct os_locale_t): Constify codeset. + (class temporaries_t): Add copy constructor. + (struct cbl_alphabet_t): Use acceptable message. + * util.cc (symbol_type_str): Use cbl_internal_error. + (cbl_field_type_str): Same. + (is_elementary): Same. + (cbl_field_t::report_invalid_initial_value): Use %qs. + (class unique_stack): Avoid %m. + (ydferror): Declare function with attributes. + (error_msg): Same. + (cobol_fileline_set): Use %<%>. + (os_locale_t): Remove use of xstrdup. + (cobol_parse_files): Quote C names in message. + (dialect_error): Use %<%>. + * util.h (cbl_message): Add attributes. + (cbl_internal_error): Same. + (cbl_err): Same. + (cbl_errx): Same. + 2025-06-16 James K. Lowden <jklowden@cobolworx.com> PR cobol/120621 diff --git a/gcc/cobol/cbldiag.h b/gcc/cobol/cbldiag.h index 6b371eb..548b0f2 100644 --- a/gcc/cobol/cbldiag.h +++ b/gcc/cobol/cbldiag.h @@ -45,8 +45,8 @@ const char * cobol_filename(); * These are user-facing messages. They go through the gcc * diagnostic framework and use text that can be localized. */ -void yyerror( const char fmt[], ... ); -bool yywarn( const char fmt[], ... ); +void yyerror( const char fmt[], ... ) ATTRIBUTE_GCOBOL_DIAG(1, 2); +bool yywarn( const char fmt[], ... ) ATTRIBUTE_GCOBOL_DIAG(1, 2); /* Location type. Borrowed from parse.h as generated by Bison. */ #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED @@ -79,18 +79,21 @@ struct YDFLTYPE #endif // an error at a location, called from the parser for semantic errors -void error_msg( const YYLTYPE& loc, const char gmsgid[], ... ); +void error_msg( const YYLTYPE& loc, const char gmsgid[], ... ) + ATTRIBUTE_GCOBOL_DIAG(2, 3); void dialect_error( const YYLTYPE& loc, const char term[], const char dialect[] ); // for CDF and other warnings that refer back to an earlier line // (not in diagnostic framework yet) -void yyerrorvl( int line, const char *filename, const char fmt[], ... ); +void yyerrorvl( int line, const char *filename, const char fmt[], ... ) + ATTRIBUTE_PRINTF_3; -void cbl_unimplementedw(const char *gmsgid, ...); // warning -void cbl_unimplemented(const char *gmsgid, ...); // error -void cbl_unimplemented_at( const YYLTYPE& loc, const char *gmsgid, ... ); +void cbl_unimplementedw(const char *gmsgid, ...) ATTRIBUTE_GCOBOL_DIAG(1, 2); // warning +void cbl_unimplemented(const char *gmsgid, ...) ATTRIBUTE_GCOBOL_DIAG(1, 2); // error +void cbl_unimplemented_at( const YYLTYPE& loc, const char *gmsgid, ... ) + ATTRIBUTE_GCOBOL_DIAG(2, 3); /* * dbgmsg produce messages not intended for the user. They cannot be localized diff --git a/gcc/cobol/cdf-copy.cc b/gcc/cobol/cdf-copy.cc index f45c466..11be9b8 100644 --- a/gcc/cobol/cdf-copy.cc +++ b/gcc/cobol/cdf-copy.cc @@ -304,7 +304,8 @@ copybook_elem_t::open_file( const char directory[], bool literally ) { dbgmsg("found copybook file %s", filename); this->source.name = xstrdup(filename); if( ! cobol_filename(this->source.name, inode_of(fd)) ) { - error_msg(source.loc, "recursive copybook: '%s' includes itself", this->source); + error_msg(source.loc, "recursive copybook: '%s' includes itself", + this->source.name); (void)! close(fd); fd = -1; } diff --git a/gcc/cobol/cdf.y b/gcc/cobol/cdf.y index 7e7d226..3344271 100644 --- a/gcc/cobol/cdf.y +++ b/gcc/cobol/cdf.y @@ -263,7 +263,7 @@ top: partials { YYACCEPT; } YYACCEPT; } | copy error { - error_msg(@error, "COPY directive must end in a '.'"); + error_msg(@error, "COPY directive must end in a %<.%>"); YYABORT; } | completes { YYACCEPT; } @@ -365,13 +365,15 @@ cdf_define: CDF_DEFINE cdf_constant NAME as cdf_expr[value] override | CDF_DEFINE FEATURE as ON { auto feature = cbl_gcobol_feature_t($2); if( ! cobol_gcobol_feature_set(feature, true) ) { - error_msg(@FEATURE, ">>DEFINE %EBCDIC-MODE is invalid within program body"); + error_msg(@FEATURE, + "%<>>DEFINE %%EBCDIC-MODE%> is invalid within program body"); } } | CDF_DEFINE FEATURE as OFF { auto feature = cbl_gcobol_feature_t($2); if( ! cobol_gcobol_feature_set(feature, false) ) { - error_msg(@FEATURE, ">>DEFINE %EBCDIC-MODE is invalid within program body"); + error_msg(@FEATURE, + "%<>>DEFINE %%EBCDIC-MODE%> is invalid within program body"); } } ; @@ -430,7 +432,7 @@ filenames: filename { auto inserted = $$->insert(symbol_index(symbol_elem_of($2))); if( ! inserted.second ) { error_msg(@2, "%s: No file-name shall be specified more than " - " once for one exception condition", $filename->name); + "once for one exception condition", $filename->name); } } ; @@ -517,7 +519,7 @@ cdf_relexpr: cdf_relexpr '<' cdf_expr { $$ = $1(@1) < $3(@3); } const char *msg = $1.string? "incommensurate comparison is FALSE: '%s' = %ld" : "incommensurate comparison is FALSE: %ld = '%s'" ; - error_msg(@1, msg); + error_msg(@1, "%s", msg); } } | cdf_relexpr NE cdf_expr @@ -531,7 +533,7 @@ cdf_relexpr: cdf_relexpr '<' cdf_expr { $$ = $1(@1) < $3(@3); } const char *msg = $1.string? "incommensurate comparison is FALSE: '%s' = %ld" : "incommensurate comparison is FALSE: %ld = '%s'" ; - error_msg(@1, msg); + error_msg(@1, "%s", msg); } } | cdf_relexpr GE cdf_expr { $$ = $1(@1) >= $3(@3); } @@ -567,7 +569,7 @@ cdf_factor: NAME { | NUMSTR { auto value = integer_literal($NUMSTR); if( !value.second ) { - error_msg(@1, "CDF error: parsed %s as %ld", + error_msg(@1, "CDF error: parsed %qs as %lld", $NUMSTR, value.first); YYERROR; } @@ -593,7 +595,7 @@ copybook_name: COPY name_one[src] copybook.library(@lib, $lib.string); if( -1 == copybook.open(@src, $src.string) ) { error_msg(@src, "could not open copybook file " - "for '%s' in '%'s'", $src.string, $lib.string); + "for %<%s%> in %<%s%>", $src.string, $lib.string); YYABORT; } } diff --git a/gcc/cobol/cobol-system.h b/gcc/cobol/cobol-system.h index ff95835..828f4f5 100644 --- a/gcc/cobol/cobol-system.h +++ b/gcc/cobol/cobol-system.h @@ -60,4 +60,10 @@ // The following "local" #include is part of the GCC core code #include "system.h" +#if (CHECKING_P && GCC_VERSION >= 4001) || GCC_VERSION == BUILDING_GCC_VERSION +#define ATTRIBUTE_GCOBOL_DIAG(m, n) __attribute__ ((__format__ (__gcc_tdiag__, m, n))) ATTRIBUTE_NONNULL(m) +#else +#define ATTRIBUTE_GCOBOL_DIAG(m, n) ATTRIBUTE_NONNULL(m) +#endif + #endif diff --git a/gcc/cobol/except.cc b/gcc/cobol/except.cc index e50fa61..3e073e2 100644 --- a/gcc/cobol/except.cc +++ b/gcc/cobol/except.cc @@ -77,7 +77,7 @@ ec_level( ec_type_t ec ) { void cbl_enabled_exception_t::dump( int i ) const { - cbl_message(2, "cbl_enabled_exception_t: %2d {%s, %s, %s, %zu}", + cbl_message(2, "cbl_enabled_exception_t: %2d {%s, %s, %zu}", i, location? "location" : " none", ec_type_str(ec), diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index f2a5d0e..0ea41f1 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -571,7 +571,7 @@ get_class_condition_string(cbl_field_t *var) { if( strlen(ach) > sizeof(ach) - 1000 ) { - cbl_internal_error("Nice try, but you can't fire me. I quit!"); + cbl_internal_error("Nice try, but you cannot fire me."); } // We are working with unquoted strings that contain the values 1 through @@ -1756,7 +1756,7 @@ get_bytes_needed(cbl_field_t *field) } default: - cbl_internal_error("%s(): Knows not the variable type %s for %s", + cbl_internal_error("%s: Knows not the variable type %s for %s", __func__, cbl_field_type_str(field->type), field->name ); @@ -2445,10 +2445,10 @@ move_tree( cbl_field_t *dest, if( !moved ) { - dbgmsg("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); - cbl_internal_error( "I don't know how to MOVE an alphabetical string to %s(%s) \n", - cbl_field_type_str(dest->type), - dest->name + dbgmsg("%10s in %s:%d", __func__, __FILE__, __LINE__ ); + cbl_internal_error( "I don%'t know how to MOVE an alphabetical string to %s(%s)", + cbl_field_type_str(dest->type), + dest->name ); return; } @@ -2514,7 +2514,7 @@ get_string_from(cbl_field_t *field) default: cbl_internal_error( - "%s(): field->type %s must be literal or alphanumeric", + "%s: %<field->type%> %s must be literal or alphanumeric", __func__, cbl_field_type_str(field->type)); break; } @@ -3449,7 +3449,7 @@ internal_perform_through( cbl_label_t *proc_1, pseudo_return_push(proc2, return_addr); // Create the code that will launch the first procedure - gg_insert_into_assembler("%s PERFORM %s THROUGH %s", + gg_insert_into_assemblerf("%s PERFORM %s THROUGH %s", ASM_COMMENT_START, proc_1->name, proc_2->name); if( !suppress_nexting ) @@ -6026,7 +6026,7 @@ tree_type_from_field_type(cbl_field_t *field, size_t &nbytes) break; default: - cbl_internal_error( "%s(): Invalid field type %s:", + cbl_internal_error( "%s: Invalid field type %s:", __func__, cbl_field_type_str(field->type)); break; @@ -6082,7 +6082,7 @@ is_valuable( cbl_field_type_t type ) { case FldPointer: return true; } - cbl_internal_error( "%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type ); + cbl_internal_error( "%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type ); return false; } @@ -7228,20 +7228,20 @@ parser_logop( struct cbl_field_t *tgt, if( tgt->type != FldConditional ) { - cbl_internal_error("parser_logop() was called with variable %s on line %d" - ", which is not a FldConditional\n", + cbl_internal_error("%<parser_logop()%> was called with variable %s on line %d" + ", which is not a FldConditional", tgt->name, cobol_location().first_line); } if( a && a->type != FldConditional ) { - cbl_internal_error("parser_logop() was called with variable %s on line %d" - ", which is not a FldConditional\n", + cbl_internal_error("%<parser_logop()%> was called with variable %s on line %d" + ", which is not a FldConditional", a->name, cobol_location().first_line); } if( b && b->type != FldConditional ) { - cbl_internal_error("parser_logop() was called with variable %s on line %d" - ", which is not a FldConditional\n", + cbl_internal_error("%<parser_logop()%> was called with variable %s on line %d" + ", which is not a FldConditional", b->name, cobol_location().first_line); } @@ -7347,9 +7347,9 @@ parser_relop( cbl_field_t *tgt, if( tgt->type != FldConditional ) { - cbl_internal_error("parser_relop() was called with variable %s, " - "which is not a FldConditional\n", - tgt->name); + cbl_internal_error("%<parser_relop%> was called with variable %qs, " + "which is not a FldConditional", + tgt->name); } static tree comp_res = gg_define_variable(INT, "..pr_comp_res", vs_file_static); @@ -7411,8 +7411,8 @@ parser_relop_long(cbl_field_t *tgt, if( tgt->type != FldConditional ) { - cbl_internal_error("parser_relop() was called with variable %s, " - "which is not a FldConditional\n", + cbl_internal_error("%<parser_relop()%> was called with variable %s, " + "which is not a FldConditional", tgt->name); } @@ -7457,8 +7457,8 @@ parser_if( struct cbl_field_t *conditional ) if( conditional->type != FldConditional ) { - cbl_internal_error("parser_if() was called with variable %s, " - "which is not a FldConditional\n", + cbl_internal_error("%<parser_if()%> was called with variable %s, " + "which is not a FldConditional", conditional->name); } @@ -7708,20 +7708,19 @@ parser_setop( struct cbl_field_t *tgt, integer_zero_node)); break; default: - dbgmsg("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); - cbl_internal_error( - "###### candidate %s has unimplemented CVT_type %d(%s)\n", - candidate->name, - candidate->type, - cbl_field_type_str(candidate->type)); + dbgmsg("%10s in %s:%d", __func__, __FILE__, __LINE__ ); + cbl_internal_error("candidate %s has unimplemented %<CVT_type%> %d(%s)", + candidate->name, + candidate->type, + cbl_field_type_str(candidate->type)); gcc_unreachable(); break; } break; default: - dbgmsg("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); - cbl_internal_error("###### unknown setop_t code %d\n", op); + dbgmsg("%10s in %s:%d", __func__, __FILE__, __LINE__ ); + cbl_internal_error("unknown %<setop_t%> code %d", op); gcc_unreachable(); break; } @@ -7917,7 +7916,7 @@ parser_perform_conditional( struct cbl_perform_tgt_t *tgt ) if( !(i < MAXIMUM_UNTILS) ) { - cbl_internal_error("%s:%d: %u exceeds MAXIMUM_UNTILS of %d, line %d", + cbl_internal_error("%s:%d: %u exceeds %<MAXIMUM_UNTILS%> of %d, line %d", __func__, __LINE__, i, MAXIMUM_UNTILS, CURRENT_LINE_NUMBER); } @@ -9151,7 +9150,7 @@ parser_file_add(struct cbl_file_t *file) if( !file ) { - cbl_internal_error("%s(): called with NULL *file", __func__); + cbl_internal_error("%s: called with NULL *file", __func__); gcc_assert(file); } @@ -9276,7 +9275,7 @@ parser_file_add(struct cbl_file_t *file) if(file->access == file_inaccessible_e) { cbl_internal_error( - "%s:%d file %s access mode is 'file_inaccessible_e' in %s", + "%s:%d file %s access mode is %<file_inaccessible_e%> in %s", current_filename.back().c_str(), CURRENT_LINE_NUMBER, file->name, @@ -9350,12 +9349,13 @@ parser_file_open( struct cbl_file_t *file, int mode_char ) if( !file ) { - cbl_internal_error("parser_file_open called with NULL *file"); + cbl_internal_error("%<parser_file_open%> called with NULL *file"); } if( !file->var_decl_node ) { - cbl_internal_error("parser_file_open for %s called with NULL var_decl_node", file->name); + cbl_internal_error("%<parser_file_open%> for %s called with NULL " + "%<var_decl_node%>", file->name); } if( mode_char == 'a' && (file->access != file_access_seq_e) ) @@ -9429,12 +9429,13 @@ parser_file_close( struct cbl_file_t *file, file_close_how_t how ) if( !file ) { - cbl_internal_error("parser_file_close called with NULL *file"); + cbl_internal_error("%<parser_file_close%> called with NULL *file"); } if( !file->var_decl_node ) { - cbl_internal_error("parser_file_close for %s called with NULL file->var_decl_node", file->name); + cbl_internal_error("%<parser_file_close%> for %s called with " + "NULL %<file->var_decl_node%>", file->name); } TRACE1 @@ -9498,27 +9499,29 @@ parser_file_read( struct cbl_file_t *file, if( !file ) { - cbl_internal_error("parser_file_read called with NULL *file"); + cbl_internal_error("%<parser_file_read%> called with NULL *file"); } if( !file->var_decl_node ) { - cbl_internal_error("parser_file_read for %s called with NULL file->var_decl_node", file->name); + cbl_internal_error("%<parser_file_read%> for %s called with " + "NULL %<file->var_decl_node%>", file->name); } if( !file ) { - cbl_internal_error("parser_file_read called with NULL *field"); + cbl_internal_error("%<parser_file_read%> called with NULL *field"); } if( !file->var_decl_node ) { - cbl_internal_error("parser_file_read for %s called with NULL field->var_decl_node", file->name); + cbl_internal_error("%<parser_file_read%> for %s called with " + "NULL %<field->var_decl_node%>", file->name); } if( file->access == file_access_seq_e && where >= 0) { - cbl_internal_error("%s:%d file %s is RELATIVE/SEQUENTIAL, but 'where' >= 0", + cbl_internal_error("%s:%d file %s is RELATIVE/SEQUENTIAL, but %<where >= 0%>", current_filename.back().c_str(), CURRENT_LINE_NUMBER, file->name); @@ -9527,7 +9530,7 @@ parser_file_read( struct cbl_file_t *file, if( file->access == file_access_rnd_e && where < 0) { - cbl_internal_error("%s:%d file %s is RELATIVE/RANDOM, but 'where' < 0", + cbl_internal_error("%s:%d file %s is RELATIVE/RANDOM, but %<where < 0%>", current_filename.back().c_str(), CURRENT_LINE_NUMBER, file->name); @@ -9615,23 +9618,23 @@ parser_file_write( cbl_file_t *file, if( !file ) { - cbl_internal_error("%s(): called with NULL *file", __func__); + cbl_internal_error("%s: called with NULL *file", __func__); } if( !file->var_decl_node ) { - cbl_internal_error("%s(): for %s called with NULL file->var_decl_node", + cbl_internal_error("%s: for %s called with NULL %<file->var_decl_node%>", __func__, file->name); } if( !file ) { - cbl_internal_error("%s(): called with NULL *field", __func__); + cbl_internal_error("%s: called with NULL *field", __func__); } if( !file->var_decl_node ) { - cbl_internal_error( "%s(): for %s called with NULL field->var_decl_node", + cbl_internal_error( "%s: for %s called with NULL %<field->var_decl_node%>", __func__, file->name); } @@ -10292,9 +10295,9 @@ inspect_replacing(int backward, } } - //fprintf(stderr, "%s(): %ld %ld\n", __func__, int_index, n_integers); + //fprintf(stderr, "%s: %ld %ld\n", __func__, int_index, n_integers); gcc_assert(int_index == n_integers); - //fprintf(stderr, "%s(): %ld %ld\n", __func__, pcbl_index, n_resolveds); + //fprintf(stderr, "%s: %ld %ld\n", __func__, pcbl_index, n_resolveds); gcc_assert(pcbl_index == n_resolveds); // We have built up an array of integers, and an array of cbl_refer_t. @@ -11477,7 +11480,7 @@ parser_sort(cbl_refer_t tableref, gcc_assert(table->var_decl_node); if( !is_table(table) ) { - cbl_internal_error( "%s(): asked to sort %s, but it's not a table", + cbl_internal_error( "%s: asked to sort %s, which is not a table", __func__, tableref.field->name); } @@ -11605,7 +11608,7 @@ parser_file_sort( cbl_file_t *workfile, else { // Having both or neither violates SORT syntax - cbl_internal_error("%s(): syntax error -- both (or neither) USING " + cbl_internal_error("%s: syntax error: both (or neither) USING " "and input-proc are specified", __func__); } @@ -11735,7 +11738,7 @@ parser_file_sort( cbl_file_t *workfile, } else { - cbl_internal_error("%s(): syntax error -- both (or neither) GIVING " + cbl_internal_error("%s: syntax error: both (or neither) GIVING " "and output-proc are specified", __func__); } } @@ -12147,7 +12150,7 @@ parser_file_merge( cbl_file_t *workfile, } else { - cbl_internal_error("%s(): syntax error -- both (or neither) " + cbl_internal_error("%s: syntax error: both (or neither) " "files and output-proc are specified", __func__); } } @@ -12798,7 +12801,7 @@ create_and_call(size_t narg, else { cbl_internal_error( - "%s(): What in the name of Nero's fiddle are we doing here?", + "%s: What in the name of Nero are we doing here?", __func__); } } @@ -13038,7 +13041,7 @@ parser_bitop( struct cbl_field_t *tgt, // tgt has to be a FldConditional if(tgt && tgt->type != FldConditional) { fprintf(stderr, - "%s(): The target %s has to be a FldConditional, not %s\n", + "%s: The target %s has to be a FldConditional, not %s\n", __func__, tgt->name, cbl_field_type_str(tgt->type)); @@ -13075,7 +13078,7 @@ parser_bitop( struct cbl_field_t *tgt, // tgt has to be a FldConditional case bit_or_op: case bit_xor_op: fprintf(stderr, - "%s(): The %s operation is not valid\n", + "%s: The %s operation is not valid\n", __func__, ops[op]); gcc_unreachable(); @@ -13122,7 +13125,7 @@ parser_bitwise_op(struct cbl_field_t *tgt, if( tgt && !is_valuable(tgt->type) && tgt->type != FldLiteralN) { fprintf(stderr, - "%s(): The target %s has to be is_valuable, not %s\n", + "%s: The target %s has to be is_valuable, not %s\n", __func__, tgt->name, cbl_field_type_str(tgt->type)); @@ -13136,7 +13139,7 @@ parser_bitwise_op(struct cbl_field_t *tgt, case bit_on_op: case bit_off_op: fprintf(stderr, - "%s(): The %s operation is not valid\n", + "%s: The %s operation is not valid\n", __func__, ops[op]); gcc_unreachable(); @@ -13749,7 +13752,7 @@ hijack_for_development(const char *funcname) // Assume that funcname is lowercase with no hyphens enter_program_common(funcname, funcname); parser_display_literal("You have been hijacked by a program named \"dubner\""); - gg_insert_into_assembler("%s HIJACKED DUBNER CODE START", ASM_COMMENT_START); + gg_insert_into_assemblerf("%s HIJACKED DUBNER CODE START", ASM_COMMENT_START); for(int i=0; i<10; i++) { @@ -13762,7 +13765,7 @@ hijack_for_development(const char *funcname) NULL_TREE); } - gg_insert_into_assembler("%s HIJACKED DUBNER CODE END", ASM_COMMENT_START); + gg_insert_into_assemblerf("%s HIJACKED DUBNER CODE END", ASM_COMMENT_START); gg_return(0); } @@ -14083,8 +14086,8 @@ mh_source_is_literalN(cbl_refer_t &destref, default: cbl_internal_error( - "In parser_move(%s to %s), the move of FldLiteralN to %s " - "hasn't been implemented", + "In %<parser_move(%s to %s)%>, the move of FldLiteralN to %s " + "is unimplemented", sourceref.field->name, destref.field->name, cbl_field_type_str(destref.field->type)); @@ -14319,8 +14322,8 @@ mh_dest_is_float( cbl_refer_t &destref, } default: - cbl_internal_error("In mh_dest_is_float(%s to %s), the " - "move of %s to %s hasn't been implemented", + cbl_internal_error("In %<mh_dest_is_float%>(%s to %s), the " + "move of %s to %s is unimplemented", sourceref.field->name, destref.field->name, cbl_field_type_str(sourceref.field->type), @@ -16349,7 +16352,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) { do { - fprintf(stderr, "( %d ) %s():", CURRENT_LINE_NUMBER, __func__); + fprintf(stderr, "( %d ) %s:", CURRENT_LINE_NUMBER, __func__); } while(0); @@ -16487,7 +16490,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) // Make sure we have a new variable to work with. if( !new_var ) { - cbl_internal_error("parser_symbol_add() was called with a NULL new_var\n"); + cbl_internal_error("%<parser_symbol_add()%> was called with a NULL %<new_var%>"); } TRACE1 @@ -16515,7 +16518,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) if( is_table(new_var) && new_var->data.capacity == 0) { cbl_internal_error( - "%s(): %2.2d %s is a table, but it improperly has a capacity of zero", + "%s: %d %s is a table, but it improperly has a capacity of zero", __func__, new_var->level, new_var->name); @@ -16555,23 +16558,20 @@ parser_symbol_add(struct cbl_field_t *new_var ) if( ancestor == new_var ) { - cbl_internal_error("parser_symbol_add(): %s is its own ancestor", - new_var->name); + cbl_internal_error("%s: %s is its own ancestor", __func__, new_var->name); } if( !ancestor && (new_var->level > LEVEL01 && new_var->level <= LEVEL49 ) ) { - cbl_internal_error("parser_symbol_add(): %2.2d %s has null ancestor", - new_var->level, - new_var->name); + cbl_internal_error("%s: %d %qs has NULL ancestor", __func__, + new_var->level, new_var->name); } // new_var's var_decl_node should be NULL at this point if( new_var->var_decl_node ) { - cbl_internal_error( "parser_symbol_add( %s ) improperly has a non-null " - "var_decl_node\n", - new_var->name); + cbl_internal_error( "%s(%s) improperly has a non-null " + "%<var_decl_node%>", __func__, new_var->name); } switch( new_var->type ) @@ -16765,7 +16765,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) && new_var->type != FldLiteralN && new_var->type != FldLiteralA ) { - cbl_internal_error( "%s(): %2.2d %s<%s> improperly has a data.capacity of zero", + cbl_internal_error( "%s: %d %s<%s> improperly has a data.capacity of zero", __func__, new_var->level, new_var->name, @@ -16832,12 +16832,10 @@ parser_symbol_add(struct cbl_field_t *new_var ) if( !bytes_to_allocate ) { - fprintf(stderr, - "bytes_to_allocate is zero for %s (symbol number " - HOST_SIZE_T_PRINT_DEC ")\n", - new_var->name, - (fmt_size_t)new_var->our_index); - gcc_assert(bytes_to_allocate); + cbl_internal_error( "%<bytes_to_allocate%> is zero for %s (symbol number " + HOST_SIZE_T_PRINT_DEC ")", + new_var->name, + (fmt_size_t)new_var->our_index); } if( new_var->type == FldIndex && new_var->level == 0 ) diff --git a/gcc/cobol/gengen.cc b/gcc/cobol/gengen.cc index a5f143c..1098225 100644 --- a/gcc/cobol/gengen.cc +++ b/gcc/cobol/gengen.cc @@ -360,7 +360,7 @@ show_type(tree type) { if( !type ) { - cbl_internal_error("The given type is not NULL, and that's just not fair"); + cbl_internal_error("The given type is not NULL, and that is just not fair"); } if( DECL_P(type) ) @@ -369,7 +369,7 @@ show_type(tree type) } if( !TYPE_P(type) ) { - cbl_internal_error("The given type is not a DECL or a TYPE"); + cbl_internal_error("The given type is not a declaration or a TYPE"); } static char ach[1024]; @@ -520,8 +520,7 @@ gg_find_field_in_struct(const tree base, const char *field_name) if( !field_decl ) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### Somebody asked for the field %s.%s, which doesn't exist", + yywarn("Somebody asked for the field %s.%s, which does not exist", IDENTIFIER_POINTER(DECL_NAME(base)), field_name); gcc_unreachable(); @@ -933,7 +932,7 @@ gg_declare_variable(tree type_decl, // causes the storage to be allocated. // It is routine to let the compiler assign names to stack variables. The - // assembly code doesn't use names for variables on the stack; they are + // assembly code does not use names for variables on the stack; they are // referenced by offsets to the base pointer. But static variables have to // have names, and there are places in my code generation -- Lord only knows // why -- where I didn't give the variables explicit names. We remedy that @@ -2161,8 +2160,7 @@ gg_printf(const char *format_string, ...) { if(nargs >= ARG_LIMIT) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### You *must* be joking!"); + yywarn("You *must* be joking"); gcc_unreachable(); } @@ -2170,10 +2168,8 @@ gg_printf(const char *format_string, ...) { // Warning: This test is not completely reliable, because a garbage // byte could have a valid TREE_CODE. But it does help. - yywarn("You nitwit!"); - yywarn("You forgot to put a NULL_TREE at the end of a " - "gg_printf() again!"); - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); + yywarn("You forgot to put a %<NULL_TREE%> at the end of a " + "%<gg_printf()%> again"); gcc_unreachable(); } @@ -2219,8 +2215,7 @@ gg_fprintf(tree fd, int nargs, const char *format_string, ...) { if(argc >= ARG_LIMIT) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### You *must* be joking!"); + yywarn("You *must* be joking"); gcc_unreachable(); } @@ -2601,10 +2596,8 @@ gg_tack_on_function_parameters(tree function_decl, ...) { // Warning: This test is not completely reliable, because a garbage // byte could have a valid TREE_CODE. But it does help. - yywarn("You nitwit!"); - yywarn("You forgot to put a NULL_TREE at the end of a " - "gg_define_function() again!"); - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); + yywarn("You forgot to put a %<NULL_TREE%> at the end of a " + "%<gg_define_function()%> again"); gcc_unreachable(); } @@ -2615,8 +2608,7 @@ gg_tack_on_function_parameters(tree function_decl, ...) nparams += 1; if(nparams > ARG_LIMIT) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### %d parameters? Really? Are you insane?",ARG_LIMIT+1); + yywarn("%d parameters? Really? Are you insane?",ARG_LIMIT+1); gcc_unreachable(); } } @@ -2657,10 +2649,8 @@ gg_define_function(tree return_type, const char *funcname, ...) { // Warning: This test is not completely reliable, because a garbage // byte could have a valid TREE_CODE. But it does help. - yywarn("You nitwit!"); - yywarn("You forgot to put a NULL_TREE at the end of a " - "gg_define_function() again!"); - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); + yywarn("You forgot to put a %<NULL_TREE%> at the end of a " + "%<gg_define_function()%> again"); gcc_unreachable(); } @@ -2671,9 +2661,7 @@ gg_define_function(tree return_type, const char *funcname, ...) nparams += 1; if(nparams > ARG_LIMIT) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### %d parameters? Really? Are you insane?", - ARG_LIMIT+1); + yywarn("%d parameters? Really? Are you insane?", ARG_LIMIT+1); gcc_unreachable(); } } @@ -2785,10 +2773,8 @@ gg_get_function_decl(tree return_type, const char *funcname, ...) { // Warning: This test is not completely reliable, because a garbage // byte could have a valid TREE_CODE. But it does help. - yywarn("You nitwit!"); - yywarn("You forgot to put a NULL_TREE at the end of a " - "gg_define_function() again!"); - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); + yywarn("You forgot to put a %<NULL_TREE%> at the end of a " + "%<gg_define_function()%> again"); gcc_unreachable(); } @@ -2799,8 +2785,7 @@ gg_get_function_decl(tree return_type, const char *funcname, ...) nparams += 1; if(nparams > ARG_LIMIT) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### %d parameters? Really? Are you insane?", + yywarn("%d parameters? Really? Are you insane?", ARG_LIMIT+1); gcc_unreachable(); } @@ -2909,7 +2894,7 @@ gg_finalize_function() /* Register this function with cgraph just far enough to get it added to our parent's nested function list. Handy, since the - C front end doesn't have such a list. */ + C front end does not have such a list. */ static cgraph_node *node = cgraph_node::get_create (current_function->function_decl); gcc_assert(node); @@ -2925,7 +2910,7 @@ gg_finalize_function() if( gg_trans_unit.function_stack.back().context_count ) { - cbl_internal_error("Residual context count!"); + cbl_internal_error("Residual context count"); } gg_trans_unit.function_stack.pop_back(); @@ -3070,8 +3055,7 @@ gg_call_expr(tree return_type, const char *function_name, ...) { if(nargs >= ARG_LIMIT) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### You *must* be joking!"); + yywarn("You *must* be joking"); gcc_unreachable(); } @@ -3127,8 +3111,7 @@ gg_call(tree return_type, const char *function_name, ...) { if(nargs >= ARG_LIMIT) { - yywarn("###### %10s in %s:%d", __func__, __FILE__,__LINE__ ); - yywarn("###### You *must* be joking!"); + yywarn("You *must* be joking"); gcc_unreachable(); } @@ -3425,7 +3408,27 @@ gg_trans_unit_var_decl(const char *var_name) } void -gg_insert_into_assembler(const char *format, ...) +gg_insert_into_assembler(const char ach[]) + { + if( !optimize ) + { + // Create the required generic tag + tree asm_expr = build5_loc( location_from_lineno(), + ASM_EXPR, + VOID, + build_string(strlen(ach), ach), + NULL_TREE, + NULL_TREE, + NULL_TREE, + NULL_TREE); + + // And insert it as a statement + gg_append_statement(asm_expr); + } + } + +void +gg_insert_into_assemblerf(const char *format, ...) { // Temporarily defeat all ASM_EXPR for optimized code per PR119214 // The correct solution using LABEL_DECL is forthcoming @@ -3444,18 +3447,6 @@ gg_insert_into_assembler(const char *format, ...) vsnprintf(ach, sizeof(ach), format, ap); va_end(ap); - // Create the required generic tag - tree asm_expr = build5_loc( location_from_lineno(), - ASM_EXPR, - VOID, - build_string(strlen(ach), ach), - NULL_TREE, - NULL_TREE, - NULL_TREE, - NULL_TREE); - //SET_EXPR_LOCATION (asm_expr, UNKNOWN_LOCATION); - - // And insert it as a statement - gg_append_statement(asm_expr); + gg_insert_into_assembler(ach); } } diff --git a/gcc/cobol/gengen.h b/gcc/cobol/gengen.h index 8c1bc8d..15c2a6b 100644 --- a/gcc/cobol/gengen.h +++ b/gcc/cobol/gengen.h @@ -539,6 +539,9 @@ extern tree gg_trans_unit_var_decl(const char *var_name); tree gg_open(tree char_star_A, tree int_B); tree gg_close(tree int_A); tree gg_get_indirect_reference(tree pointer, tree offset); -void gg_insert_into_assembler(const char *format, ...); + +void gg_insert_into_assembler(const char ach[]); +void gg_insert_into_assemblerf(const char *format, ...) ATTRIBUTE_PRINTF_1; + void gg_modify_function_type(tree function_decl, tree return_type); #endif diff --git a/gcc/cobol/genmath.cc b/gcc/cobol/genmath.cc index bf3885b..0a1c12d 100644 --- a/gcc/cobol/genmath.cc +++ b/gcc/cobol/genmath.cc @@ -1383,12 +1383,12 @@ parser_op( struct cbl_refer_t cref, break; } default: - cbl_internal_error( "parser_op() doesn't know how to " - "evaluate \"%s = %s %c %s\"\n", - cref.field->name, - aref.field->name, - op, - bref.field->name); + cbl_internal_error( "%<parser_op()%> doesn%'t know how to " + "evaluate %<%s = %s %c %s%>", + cref.field->name, + aref.field->name, + op, + bref.field->name); break; } } diff --git a/gcc/cobol/genutil.cc b/gcc/cobol/genutil.cc index 8ec7a78..1d921a3 100644 --- a/gcc/cobol/genutil.cc +++ b/gcc/cobol/genutil.cc @@ -737,7 +737,7 @@ get_binary_value( tree value, { if( SCALAR_FLOAT_TYPE_P(value) ) { - cbl_internal_error("Can't get float value from %s", field->name); + cbl_internal_error("cannot get %<float%> value from %s", field->name); } else { diff --git a/gcc/cobol/lexio.cc b/gcc/cobol/lexio.cc index 888cce1..754a948 100644 --- a/gcc/cobol/lexio.cc +++ b/gcc/cobol/lexio.cc @@ -745,7 +745,7 @@ parse_replacing_pair( const char *stmt, const char *estmt ) { } } if( pair.stmt.p ) { - yywarn("CDF syntax error '%*s'", (int)pair.stmt.size(), pair.stmt.p); + yywarn("CDF syntax error '%.*s'", (int)pair.stmt.size(), pair.stmt.p); } else { // This eliminated a compiler warning about "format-overflow" @@ -1413,7 +1413,7 @@ preprocess_filter_add( const char input[] ) { auto filename = find_filter(filter.c_str()); if( !filename ) { - yywarn("preprocessor '%s/%s' not found", getcwd(NULL, 0), filter); + yywarn("preprocessor '%s/%s' not found", getcwd(NULL, 0), filter.c_str()); return false; } preprocessor_filters.push_back( std::make_pair(xstrdup(filename), options) ); @@ -1546,7 +1546,7 @@ int cdftext::open_input( const char filename[] ) { int fd = open(filename, O_RDONLY); if( fd == -1 ) { - dbgmsg( "could not open '%s': %m", filename ); + dbgmsg( "could not open '%s': %s", filename, xstrerror(errno) ); } verbose_file_reader = NULL != getenv("GCOBOL_TEMPDIR"); diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y index 3afa20f..99295e8 100644 --- a/gcc/cobol/parse.y +++ b/gcc/cobol/parse.y @@ -1482,7 +1482,7 @@ program_id: PROGRAM_ID dot namestr[name] program_as program_attrs[attr] dot const char *name = string_of($name); parser_enter_program( name, false, &main_error ); if( main_error ) { - error_msg(@name, "PROGRAM-ID 'main' is invalid with -main option"); + error_msg(@name, "PROGRAM-ID 'main' is invalid with %<-main%> option"); YYERROR; } @@ -1518,7 +1518,8 @@ function_id: FUNCTION '.' NAME program_as program_attrs[attr] '.' int main_error = 0; parser_enter_program( $NAME, true, &main_error ); if( main_error ) { - error_msg(@NAME, "FUNCTION-ID 'main' is invalid with -main option"); + error_msg(@NAME, "FUNCTION-ID %<main%> is invalid " + "with %<-main%> option"); YYERROR; } if( symbols_begin() == symbols_end() ) { @@ -1589,7 +1590,7 @@ opt_binary: FLOAT_BINARY default_kw is HIGH_ORDER_LEFT { cbl_unimplementedw("HIGH-ORDER-LEFT was ignored"); if( ! current.option_binary(cbl_options_t::high_order_left_e) ) { - error_msg(@3, "unable to set HIGH_ORDER_LEFT"); + error_msg(@3, "unable to set %<HIGH_ORDER_LEFT%>"); } } | FLOAT_BINARY default_kw is HIGH_ORDER_RIGHT[opt] @@ -2520,7 +2521,7 @@ dev_mnemonic: device_name is NAME { auto p = cmd_or_env_special_of($device); if( !p ) { - error_msg(@device, "%s is not a device name"); + error_msg(@device, "%s is not a device name", $device); YYERROR; } @@ -2646,7 +2647,7 @@ alphabet_seq: alphabet_lit[low] alphabet_etc: alphabet_lit { if( $1.len > 1 ) { - error_msg(@1, "'%c' can be only a single letter", $1.data); + error_msg(@1, "%qs can be only a single letter", $1.data); YYERROR; } $$ = (unsigned char)$1.data[0]; @@ -2912,7 +2913,7 @@ fd_clause: record_desc f->varying_size.explicitly = f->varies(); if( f->varying_size.max != 0 ) { if( !(f->varying_size.min <= f->varying_size.max) ) { - error_msg(@1, "%zu must be <= %zu", + error_msg(@1, "%zu must be less than or equal to %zu", f->varying_size.min, f->varying_size.max); YYERROR; } @@ -2988,7 +2989,7 @@ rec_contains: NUMSTR[min] { } $$.max = n; if( !($$.min < $$.max) ) { - error_msg(@max, "FROM (%xz) must be less than TO (%zu)", + error_msg(@max, "FROM (%zu) must be less than TO (%zu)", $$.min, $$.max); YYERROR; } @@ -3184,7 +3185,7 @@ field: cdf } initial = string_of(field.data.value_of()); if( !initial ) { - error_msg(@1, xstrerror(errno)); + error_msg(@1, "could not convert value to string"); YYERROR; } char decimal = symbol_decimal_point(); @@ -3638,7 +3639,7 @@ data_descr1: level_name } if( field_index($thru) <= field_index($orig) ) { error_msg(@orig, "cannot RENAME %s %s THRU %s %s " - "because they're in the wrong order", + "because they are in the wrong order", $orig->level_str(), name_of($orig), $thru->level_str(), name_of($thru)); YYERROR; @@ -3680,7 +3681,7 @@ data_descr1: level_name case FldNumericEdited: if( $field->has_attr(signable_e) ) { error_msg(@2, "%s has 'S' in PICTURE, cannot be BLANK WHEN ZERO", - $field->name, cbl_field_type_str($field->type) ); + $field->name ); } break; default: @@ -3891,9 +3892,8 @@ data_clauses: data_clause auto redefined = symbol_redefines(field); if( redefined && redefined->type == FldPointer ) { if( yydebug ) { - yywarn("expanding %s size from %u bytes to " - HOST_WIDE_INT_PRINT " " - "because it redefines %s with USAGE POINTER", + yywarn("expanding %s size from %u bytes to %wd " + "because it redefines %s with %<USAGE POINTER%>", field->name, field->size(), int_size_in_bytes(ptr_type_node), redefined->name); @@ -3986,7 +3986,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft] field->data.capacity = type_capacity(field->type, $4); field->data.digits = $4; if( long(field->data.digits) != $4 ) { - error_msg(@2, "indicated size would be %ld bytes, " + error_msg(@2, "indicated size would be %d bytes, " "maximum data item size is %u", $4, UINT32_MAX); } @@ -4056,7 +4056,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft] (dialect_gnu() || dialect_mf()) ) { // PIC X COMP-X or COMP-9 if( ! field->has_attr(all_x_e) ) { - error_msg(@2, "COMP PICTURE requires all X's or all 9's"); + error_msg(@2, "COMP PICTURE requires all X%'s or all 9%'s"); YYERROR; } } else { @@ -4091,7 +4091,7 @@ picture_clause: PIC signed nps[fore] nines nps[aft] } ERROR_IF_CAPACITY(@PIC, field); if( !is_numeric_edited($picture) ) { - error_msg(@picture, numed_message); + error_msg(@picture, "%s", numed_message); YYERROR; } field->data.picture = $picture; @@ -4170,7 +4170,7 @@ alphanum_part: ALNUM[picture] count $$.nbyte += count; // AX9(3) has count 5 } if( count < 0 ) { - error_msg(@2, "PICTURE count '(%d)' is negative", count ); + error_msg(@2, "PICTURE count %<(%d)%> is negative", count ); YYERROR; } } @@ -4189,7 +4189,7 @@ nine: %empty { $$ = 0; } { $$ = $1; if( $$ == 0 ) { - error_msg(@1, "'(0)' invalid in PICTURE (ISO 2023 13.18.40.3)"); + error_msg(@1, "%<(0)%> invalid in PICTURE (ISO 2023 13.18.40.3)"); } } ; @@ -4203,14 +4203,14 @@ count: %empty { $$ = 0; } REAL_VALUE_TYPE rn = numstr2i($NUMSTR.string, $NUMSTR.radix); $$ = real_to_integer (&rn); if( $$ == 0 ) { - error_msg(@2, "'(0)' invalid in PICTURE (ISO 2023 13.18.40.3)"); + error_msg(@2, "%<0%> invalid in PICTURE (ISO 2023 13.18.40.3)"); } } | '(' NAME ')' { auto value = cdf_value($NAME); if( ! (value && value->is_numeric()) ) { - error_msg(@NAME, "PICTURE '(%s)' requires a CONSTANT value", $NAME ); + error_msg(@NAME, "PICTURE %qs requires a CONSTANT value", $NAME ); YYERROR; } int nmsg = 0; @@ -4223,13 +4223,13 @@ count: %empty { $$ = 0; } if( !real_identical (TREE_REAL_CST_PTR (field->data.value_of()), &vi) ) { nmsg++; - error_msg(@NAME, "invalid PICTURE count '(%s)'", + error_msg(@NAME, "invalid PICTURE count %<(%s)%>", field->data.initial ); } } $$ = value->as_number(); if( $$ <= 0 && !nmsg) { - error_msg(@NAME, "invalid PICTURE count '(%s)'", $NAME ); + error_msg(@NAME, "invalid PICTURE count %<(%s)%>", $NAME ); } } ; @@ -4974,12 +4974,11 @@ statements: statement { $$ = $1; } statement: error { if( current.declarative_section_name() ) { - error_msg(@1, "missing END DECLARATIVES or SECTION name", - nparse_error); + error_msg(@1, "missing END DECLARATIVES or SECTION name"); YYABORT; } if( max_errors_exceeded(nparse_error) ) { - error_msg(@1, "max errors %d reached", nparse_error); + error_msg(@1, "max errors %zu reached", nparse_error); YYABORT; } } @@ -5692,7 +5691,8 @@ end_program: end_program1[end] '.' gcc_unreachable(); } if( !matches ) { - error_msg(@end, "END %s %s' does not match IDENTIFICATION DIVISION '%s'", + error_msg(@end, "END %s %s does not match " + "%<IDENTIFICATION DIVISION %s%>", token_name, name, prog->name); YYERROR; } @@ -5723,9 +5723,9 @@ end_program: end_program1[end] '.' token_name = "FUNCTION"; break; default: - cbl_internal_error( "END token invalid"); + cbl_internal_error( "%<END%> token invalid"); } - error_msg(@end, "END %s requires NAME before '.'", token_name); + error_msg(@end, "%<END%> %s requires %<NAME%> before %<.%>", token_name); YYERROR; } ; @@ -6776,7 +6776,7 @@ move: MOVE scalar TO move_tgts[tgts] { statement_begin(@1, MOVE); if( $scalar->field->type == FldIndex ) { - error_msg(@1, "'%s' cannot be MOVEd because it's an INDEX", + error_msg(@1, "%qs cannot be MOVEd because it is an %<INDEX%>", name_of($scalar->field) ); YYERROR; } @@ -7168,20 +7168,20 @@ section_kw: SECTION { if( $1 ) { if( *$1 == '-' ) { - error_msg(@1, "SECTION segment %<%s%> is negative", $1); + error_msg(@1, "SECTION segment %qs is negative", $1); } else { if( dialect_ibm() ) { int sectno; sscanf($1, "%d", §no); if( ! (0 <= sectno && sectno <= 99) ) { - error_msg(@1, "SECTION segment %<%s%> must be 0-99", $1); + error_msg(@1, "SECTION segment %qs must be 0-99", $1); } else { if(false) { // stand-in for warning, someday. - yywarn("SECTION segment %<%s%> was ignored", $1); + yywarn("SECTION segment %qs was ignored", $1); } } } else { - cbl_unimplemented("SECTION segment %<%s%> is not ISO syntax", $1); + cbl_unimplemented("SECTION segment %qs is not ISO syntax", $1); } } } @@ -7932,7 +7932,7 @@ raise: RAISE EXCEPTION NAME "EXCEPTION CONDITION: %s", $NAME); YYERROR; } - cbl_unimplemented("RAISE <EXCEPTION OBJECT>"); + cbl_unimplemented("RAISE %<EXCEPTION OBJECT%>"); YYERROR; } ; @@ -8009,7 +8009,7 @@ read_body: NAME read_next read_into read_key YYERROR; } if( $read_key->field && $read_next < 0 ) { - error_msg(@1, "cannot read NEXT with KEY", $$->name); + error_msg(@1, "cannot read NEXT with KEY %qs", $$->name); YYERROR; } @@ -8803,7 +8803,7 @@ search_term: scalar[key] '=' search_expr[sarg] } if( dimensions($key->field) < $key->nsubscript() ) { error_msg(@1, "too many subscripts: " - "%zu for table of %zu dimensions", + "%u for table of %zu dimensions", $key->nsubscript(), dimensions($key->field) ); YYERROR; } @@ -9137,7 +9137,7 @@ inspect: INSPECT backward inspected TALLYING tallies if( is_literal(match) && is_literal(replace) ) { if( !$match->all && !$replace_oper->all) { if( match->data.capacity != replace->data.capacity ) { - error_msg(@match, "'%s', size %u NOT EQUAL '%s', size %u", + error_msg(@match, "%qs, size %u NOT EQUAL %qs, size %u", nice_name_of(match), match->data.capacity, nice_name_of(replace), replace->data.capacity); YYERROR; @@ -10212,8 +10212,8 @@ intrinsic: function_udf args.data()); if( p != NULL ) { auto loc = symbol_field_location(field_index(p->field)); - error_msg(loc, "FUNCTION %s has " - "inconsistent parameter type %zu ('%s')", + error_msg(loc, "FUNCTION %qs has " + "inconsistent parameter type %zu (%qs)", keyword_str($1), p - args.data(), name_of(p->field) ); YYERROR; } @@ -10290,7 +10290,7 @@ intrinsic: function_udf location_set(@1); $$ = new_alphanumeric("FIND-STRING"); /* auto r1 = new_reference(new_literal(strlen($r1), $r1, quoted_e)); */ - cbl_unimplemented("FIND_STRING"); + cbl_unimplemented("%<FIND_STRING%>"); /* if( ! intrinsic_call_4($$, FIND_STRING, r1, $r2) ) YYERROR; */ } @@ -10757,7 +10757,7 @@ numval_locale: %empty { $$.arg2 = cbl_refer_t::empty(); } | LOCALE NAME { $$.is_locale = true; $$.arg2 = NULL; - cbl_unimplemented("NUMVAL_C LOCALE"); YYERROR; + cbl_unimplemented("%<NUMVAL_C LOCALE%>"); YYERROR; } | varg { $$.is_locale = false; $$.arg2 = $1; } ; @@ -11541,7 +11541,7 @@ relop_invert(relop_t op) { case ge_op: return lt_op; case gt_op: return le_op; } - cbl_errx( "%s:%d: invalid relop_t %d", __func__, __LINE__, op); + cbl_internal_error("%s:%d: invalid %<relop_t%> %d", __func__, __LINE__, op); return relop_t(0); // not reached } @@ -11834,7 +11834,7 @@ current_t::udf_args_valid( const cbl_label_t *L, auto tgt = cbl_field_of(symbol_at(udf.linkage_fields.at(i).isym)); if( ! valid_move(tgt, arg.field) ) { auto loc = symbol_field_location(field_index(arg.field)); - error_msg(loc, "FUNCTION %s arg %zu, '%s' cannot be passed to %s, type %s", + error_msg(loc, "FUNCTION %s argument %zu, '%s' cannot be passed to %s, type %s", L->name, i, arg.field->pretty_name(), tgt->pretty_name(), 3 + cbl_field_type_str(tgt->type) ); return false; @@ -12032,7 +12032,7 @@ struct stringify_src_t : public cbl_string_src_t { protected: static void dump_input( const cbl_refer_t& refer ) { - yywarn( "%s:\t%s", __func__, field_str(refer.field) ); + yywarn( "%s: %s", __func__, field_str(refer.field) ); } }; @@ -12341,7 +12341,7 @@ numstr2i( const char input[], radix_t radix ) { case boolean_e: for( const char *p = input; *p != '\0'; p++ ) { if( ssize_t(8 * sizeof(integer) - 1) < p - input ) { - yywarn("'%s' was accepted as %d", input, integer); + yywarn("'%s' was accepted as %zu", input, integer); break; } switch(*p) { @@ -12351,7 +12351,7 @@ numstr2i( const char input[], radix_t radix ) { integer |= ((*p) == '0' ? 0 : 1); break; default: - yywarn("'%s' was accepted as %d", input, integer); + yywarn("'%s' was accepted as %zu", input, integer); break; } } @@ -12359,7 +12359,7 @@ numstr2i( const char input[], radix_t radix ) { return output; } if( erc == -1 ) { - yywarn("'%s' was accepted as %lld", input, output); + yywarn("'%s' was accepted as %wd", input, integer); } return output; } @@ -12982,7 +12982,7 @@ literal_attr( const char prefix[] ) { } // must be [BN]X - cbl_internal_error("'%s': invalid literal prefix", prefix); + cbl_internal_error("invalid literal prefix: %qs", prefix); gcc_unreachable(); return none_e; } diff --git a/gcc/cobol/parse_ante.h b/gcc/cobol/parse_ante.h index ffb4c98..8194614 100644 --- a/gcc/cobol/parse_ante.h +++ b/gcc/cobol/parse_ante.h @@ -335,7 +335,7 @@ struct evaluate_elem_t { label.line = yylineno; if( -1 == snprintf(label.name, sizeof(label.name), "%.*s_%d", (int)sizeof(label.name)-6, skel, yylineno) ) { - yyerror("could not create unique label '%s_%d' because it is too long", + yyerror("could not create unique label %<%s_%d%> because it is too long", skel, yylineno); } } @@ -2116,7 +2116,7 @@ static class current_t { if( ! dialect_ibm() ) { error_msg(loc, "Per ISO a program with DECLARATIVES must begin with a SECTION, " - "requires -dialect ibm"); + "requires %<-dialect ibm%>"); } } } @@ -2558,7 +2558,8 @@ is_callable( const cbl_field_t *field ) { case FldPointer: return true; } - cbl_internal_error( "%s:%d: invalid symbol_type_t %d", __func__, __LINE__, field->type ); + cbl_internal_error( "%s:%d: invalid %<symbol_type_t%> %d", + __func__, __LINE__, field->type ); return false; } diff --git a/gcc/cobol/parse_util.h b/gcc/cobol/parse_util.h index 11b86a3..006cea7 100644 --- a/gcc/cobol/parse_util.h +++ b/gcc/cobol/parse_util.h @@ -348,7 +348,7 @@ intrinsic_invalid_parameter( int token, return token == descr.token; } ); if( p == function_descrs_end ) { - cbl_internal_error( "%s: intrinsic function %s not found", + cbl_internal_error( "%s: intrinsic function %qs not found", __func__, keyword_str(token) ); } diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l index 52a0b94..9b586e9 100644 --- a/gcc/cobol/scan.l +++ b/gcc/cobol/scan.l @@ -982,7 +982,7 @@ USE({SPC}FOR)? { return USE; } BINARY-LONG { return bcomputable(FldNumericBin5, 4); } BINARY-DOUBLE { return bcomputable(FldNumericBin5, 8); } BINARY-LONG-LONG { if( ! dialect_mf() ) { - error_msg(yylloc, "%s requires -dialect mf", yytext); + dialect_error(yylloc, yytext, "mf"); } return bcomputable(FldNumericBin5, 8); } @@ -993,7 +993,7 @@ USE({SPC}FOR)? { return USE; } FLOAT-BINARY-32 { return ucomputable(FldFloat, 4); } FLOAT-BINARY-64 { return ucomputable(FldFloat, 8); } FLOAT-BINARY-128 { return ucomputable(FldFloat, 16); } - FLOAT-DECIMAL-(16|34) { not_implemented("USAGE type: FLOAT_DECIMAL"); + FLOAT-DECIMAL-(16|34) { not_implemented("USAGE type: %<FLOAT_DECIMAL%>"); return FLOAT_DECIMAL; // causes syntax error } /* 21) The representation and length of a data item described with USAGE @@ -1019,7 +1019,7 @@ USE({SPC}FOR)? { return USE; } POINTER { yylval.field_attr = none_e; return POINTER; } PROCEDURE-POINTER { if( dialect_gcc() ) { - error_msg(yylloc, "%s requires -dialect ibm or mf", yytext); + dialect_error(yylloc, yytext, "ibm or mf"); } yylval.field_attr = prog_ptr_e; return POINTER; // return it anyway @@ -2482,10 +2482,9 @@ BASIS { yy_push_state(basis); return BASIS; } <<EOF>> { if( YY_START == quoted1 || YY_START == quoted2 ) { - error_msg(yylloc, "syntax error: unterminated string '%s'", + error_msg(yylloc, "syntax error: unterminated string %<%s%>", tmpstring); return NO_CONDITION; - cbl_internal_error(""); } yypop_buffer_state(); diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h index 21e89e4..037c929 100644 --- a/gcc/cobol/scan_ante.h +++ b/gcc/cobol/scan_ante.h @@ -159,11 +159,11 @@ numstr_of( const char string[], radix_t radix = decimal_e ) { // exponent is implementor-defined." (We allow 9999.) nx = std::count_if(p, eoinput, fisdigit); if( 4 < nx ) { - error_msg(yylloc, "exponent %s more than 4 digits", ++p); + error_msg(yylloc, "exponent %qs more than 4 digits", ++p); return NO_CONDITION; } if( eoinput != std::find(p, eoinput, symbol_decimal_point()) ) { - error_msg(yylloc, "exponent includes decimal point", ++p); + error_msg(yylloc, "exponent %qs includes decimal point", ++p); return NO_CONDITION; } @@ -187,7 +187,7 @@ numstr_of( const char string[], radix_t radix = decimal_e ) { } } if( 1 < std::count(input, eoinput, symbol_decimal_point()) ) { - error_msg(yylloc, "invalid numeric literal", ++p); + error_msg(yylloc, "invalid numeric literal %qs", ++p); return NO_CONDITION; } @@ -295,7 +295,7 @@ static class parsing_status_t : public std::stack<cdf_status_t> { void splat() const { int i=0; for( const auto& status : c ) { - yywarn( "%4d\t%s", ++i, status.str() ); + yywarn( "%d %s", ++i, status.str() ); } } } parsing; @@ -305,7 +305,7 @@ void field_done() { orig_picture[0] = '\0'; parsing.need_level(true); } static int scanner_token() { if( parsing.empty() ) { - error_msg(yylloc, ">>ELSE or >>END-IF without >>IF"); + error_msg(yylloc, "%<>>ELSE%> or %<>>END-IF%> without %<>>IF%>"); return NO_CONDITION; } return parsing.top().token; @@ -317,33 +317,32 @@ bool scanner_normal() { return parsing.normal(); } void scanner_parsing( int token, bool tf ) { parsing.push( cdf_status_t(token, tf) ); if( yydebug ) { - yywarn("%10s: parsing now %5s, depth %lu", - keyword_str(token), boolalpha(parsing.on()), - gb4(parsing.size())); + yywarn("%s: parsing now %s, depth %zu", + keyword_str(token), boolalpha(parsing.on()), parsing.size()); parsing.splat(); } } void scanner_parsing_toggle() { if( parsing.empty() ) { - error_msg(yylloc, ">>ELSE without >>IF"); + error_msg(yylloc, "%<>>ELSE%> without %<>>IF%>"); return; } parsing.top().toggle(); if( yydebug ) { - yywarn("%10s: parsing now %5s", + yywarn("%s: parsing now %s", keyword_str(CDF_ELSE), boolalpha(parsing.on())); } } void scanner_parsing_pop() { if( parsing.empty() ) { - error_msg(yylloc, ">>END-IF without >>IF"); + error_msg(yylloc, "%<>>END-IF%> without %<>>IF%>"); return; } parsing.pop(); if( yydebug ) { - yywarn("%10s: parsing now %5s, depth %lu", + yywarn("%s: parsing now %s, depth %zu", keyword_str(CDF_END_IF), boolalpha(parsing.on()), - gb4(parsing.size())); + parsing.size()); parsing.splat(); } } @@ -792,7 +791,7 @@ typed_name( const char name[] ) { return cbl_field_of(e)->level == 88? NAME88 : CLASS_NAME; break; default: - yywarn("%s:%d: invalid symbol type %s for symbol \"%s\"", + yywarn("%s:%d: invalid symbol type %s for symbol %qs", __func__, __LINE__, cbl_field_type_str(type), name); return NAME; } diff --git a/gcc/cobol/scan_post.h b/gcc/cobol/scan_post.h index 385ea67..a273da9 100644 --- a/gcc/cobol/scan_post.h +++ b/gcc/cobol/scan_post.h @@ -297,7 +297,7 @@ prelex() { token = LEVEL; break; case YDF_NUMBER: - if( yy_flex_debug ) yywarn("final token is YDF_NUMBER"); + if( yy_flex_debug ) yywarn("final token is %<YDF_NUMBER%>"); yylval.number = ydflval.number; token = LEVEL; break; diff --git a/gcc/cobol/show_parse.h b/gcc/cobol/show_parse.h index d417af3..db24807 100644 --- a/gcc/cobol/show_parse.h +++ b/gcc/cobol/show_parse.h @@ -424,30 +424,31 @@ extern bool cursor_at_sol; // Use CHECK_FIELD when a should be non-null, and a->var_decl_node also should // by non-null: -#define CHECK_FIELD(a) \ - do{ \ - if(!a) \ - { \ - yywarn("%s(): parameter " #a " is NULL", __func__); \ - gcc_unreachable(); \ - } \ - if( !a->var_decl_node && a->type != FldConditional && a->type != FldLiteralA) \ - { \ - yywarn("%s() parameter " #a " is variable %s<%s> with NULL var_decl_node", \ - __func__, \ - a->name, \ - cbl_field_type_str(a->type) ); \ - gcc_unreachable(); \ - } \ - }while(0); - -#define CHECK_LABEL(a) \ - do{ \ - if(!a) \ - { \ - yywarn("%s(): parameter " #a " is NULL", __func__); \ - gcc_unreachable(); \ - } \ +#define CHECK_FIELD(a) \ + do { \ + if(!a) \ + { \ + yywarn("%s: parameter %<" #a "%> is NULL", __func__); \ + gcc_unreachable(); \ + } \ + if( !a->var_decl_node && a->type != FldConditional && a->type != FldLiteralA) \ + { \ + yywarn("%s: parameter %<" #a "%> is variable " \ + "%s<%s> with NULL %<var_decl_node%>", \ + __func__, \ + a->name, \ + cbl_field_type_str(a->type) ); \ + gcc_unreachable(); \ + } \ + } while(0); + +#define CHECK_LABEL(a) \ + do{ \ + if(!a) \ + { \ + yywarn("%s: parameter %<" #a "%> is NULL", __func__); \ + gcc_unreachable(); \ + } \ }while(0); #ifdef INCORPORATE_ANALYZER diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc index d75ca29..089c9c1 100644 --- a/gcc/cobol/symbols.cc +++ b/gcc/cobol/symbols.cc @@ -2836,7 +2836,7 @@ seek_parent( const symbol_elem_t *e, size_t level ) { struct symbol_elem_t * symbol_field_same_as( cbl_field_t *tgt, const cbl_field_t *src ) { if( target_in_src(tgt, src) ) { - ERROR_FIELD(tgt, "%s %s may not reference itself as part of %s %s", + ERROR_FIELD(tgt, "%s %s may not reference itself as part of %s %s", tgt->level_str(), tgt->name, src->level_str(), src->name); return NULL; } @@ -3088,7 +3088,7 @@ cbl_alphabet_t::assign( const YYLTYPE& loc, unsigned char ch, unsigned char high return true; } auto taken = alphabet[ch]; - error_msg(loc, "ALPHABET %s, character '%c' (X'%x') " + error_msg(loc, "ALPHABET %s, character %<%c%> (X%'%x%') " "in position %d already defined at position %d", name, ISPRINT(ch)? ch : '?', ch, @@ -3493,7 +3493,7 @@ cbl_field_t::internalize() { static const size_t noconv = size_t(-1); if (cd == (iconv_t)-1) { - yywarn("failed iconv_open tocode = '%s' fromcode = %s", tocode, fromcode); + yywarn("failed %<iconv_open%> tocode = %<%s%> fromcode = %s", tocode, fromcode); } bool using_assumed = fromcode == os_locale.assumed; diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h index 84a984e..c09fbcc 100644 --- a/gcc/cobol/symbols.h +++ b/gcc/cobol/symbols.h @@ -131,13 +131,13 @@ is_numeric( cbl_field_type_t type ) { case FldIndex: return true; } - yywarn( "%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type ); + cbl_internal_error( "%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type ); return false; } struct os_locale_t { char assumed[16]; - char *codeset; + const char *codeset; }; const char * cbl_field_attr_str( cbl_field_attr_t attr ); @@ -1216,6 +1216,8 @@ class temporaries_t { literal_an() : is_quoted(false), value("???") {} literal_an( const char value[], bool is_quoted ) : is_quoted(is_quoted), value(value) {} + literal_an( const literal_an& that ) + : is_quoted(that.is_quoted), value(that.value) {} literal_an& operator=( const literal_an& that ) { is_quoted = that.is_quoted; value = that.value; @@ -1495,7 +1497,7 @@ struct cbl_alphabet_t { } void dump() const { - yywarn("'%s': %s, '%c' to '%c' (low 0x%02x, high 0x%02x)", + yywarn("%qs: %s, %<%c%> to %<%c%> (low 0x%x, high 0x%x)", name, encoding_str(encoding), low_index, last_index, low_index, high_index); if( encoding == custom_encoding_e ) { diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc index b6c9280..d8423e0 100644 --- a/gcc/cobol/util.cc +++ b/gcc/cobol/util.cc @@ -130,7 +130,7 @@ symbol_type_str( enum symbol_type_t type ) case SymDataSection: return "SymDataSection"; } - dbgmsg("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type); + cbl_internal_error("%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type); return "???"; } @@ -179,7 +179,7 @@ cbl_field_type_str( enum cbl_field_type_t type ) case FldBlob: return "FldBlob"; } - dbgmsg("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type); + cbl_internal_error("%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type); return "???"; } @@ -479,7 +479,7 @@ is_elementary( enum cbl_field_type_t type ) case FldFloat: return true; // takes up space } - dbgmsg("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type); + cbl_internal_error("%s:%d: invalid %<symbol_type_t%> %d", __func__, __LINE__, type); return false; } @@ -902,8 +902,8 @@ cbl_field_t::report_invalid_initial_value(const YYLTYPE& loc) const { return TOUPPER(ch) == 'E'; } ); if( !has_exponent && data.precision() < pend - p ) { - error_msg(loc, "%s cannot represent VALUE '%s' exactly (max .%zu)", - name, data.initial, pend - p); + error_msg(loc, "%s cannot represent VALUE %qs exactly (max %c%zu)", + name, data.initial, '.', pend - p); } } } @@ -1805,7 +1805,7 @@ class unique_stack : public std::stack<input_file_t> (fmt_size_t)(c.size() - --n), v.lineno, no_wd(wd, v.name) ); } } else { - dbgmsg("unable to get current working directory: %m"); + dbgmsg("unable to get current working directory: %s", xstrerror(errno)); } free(wd); } @@ -1953,6 +1953,8 @@ verify_format( const char gmsgid[] ) { static const diagnostic_option_id option_zero; size_t parse_error_inc(); +void ydferror( const char gmsgid[], ... ) ATTRIBUTE_GCOBOL_DIAG(1, 2); + void ydferror( const char gmsgid[], ... ) { verify_format(gmsgid); @@ -2029,6 +2031,9 @@ void error_msg( const YYLTYPE& loc, const char gmsgid[], ... ) { ERROR_MSG_BODY } +void error_msg( const YDFLTYPE& loc, const char gmsgid[], ... ) + ATTRIBUTE_GCOBOL_DIAG(2, 3); + void error_msg( const YDFLTYPE& loc, const char gmsgid[], ... ) { ERROR_MSG_BODY } @@ -2119,7 +2124,7 @@ cobol_fileline_set( const char line[] ) { dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); return line; } - error_msg(yylloc, "invalid #line directive: %s", line ); + error_msg(yylloc, "invalid %<#line%> directive: %s", line ); return line; } @@ -2129,7 +2134,7 @@ cobol_fileline_set( const char line[] ) { int fileline; if( 1 != sscanf(line_str, "%d", &fileline) ) - yywarn("could not parse line number %s from #line directive", line_str); + yywarn("could not parse line number %s from %<#line%> directive", line_str); input_file_t input_file( filename, ino_t(0), fileline ); // constructor sets inode @@ -2216,19 +2221,9 @@ cobol_set_debugging( bool flex, bool yacc, bool parser ) yy_flex_debug = flex? 1 : 0; ydfdebug = yydebug = yacc? 1 : 0; f_trace_debug = parser? 1 : 0; - - char *ind = getenv("INDICATOR_COLUMN"); - if( ind ) { - int col; - if( 1 != sscanf(ind, "%d", &col) ) { - yywarn("ignored non-integer value for INDICATOR_COLUMN=%s", ind); - } - cobol_set_indicator_column(col); - } } -os_locale_t os_locale = { "UTF-8", xstrdup("C.UTF-8") }; - +os_locale_t os_locale = { "UTF-8", "C.UTF-8" }; void cobol_parse_files (int nfile, const char **files) @@ -2239,7 +2234,7 @@ cobol_parse_files (int nfile, const char **files) } else { char *codeset = nl_langinfo(CODESET); if( ! codeset ) { - yywarn("nl_langinfo failed after setlocale succeeded"); + yywarn("%<nl_langinfo%> failed after %<setlocale()%> succeeded"); } else { os_locale.codeset = codeset; } @@ -2351,7 +2346,7 @@ dbgmsg(const char *msg, ...) { void dialect_error( const YYLTYPE& loc, const char term[], const char dialect[] ) { - error_msg(loc, "%s is not ISO syntax, requires -dialect %s", + error_msg(loc, "%s is not ISO syntax, requires %<-dialect %s%>", term, dialect); } diff --git a/gcc/cobol/util.h b/gcc/cobol/util.h index 54d3930..9388b50 100644 --- a/gcc/cobol/util.h +++ b/gcc/cobol/util.h @@ -31,11 +31,13 @@ #ifndef _UTIL_H_ #define _UTIL_H_ -void cbl_message(int fd, const char *format_string, ...); -void cbl_internal_error(const char *format_string, ...); +void cbl_message(int fd, const char *format_string, ...) + ATTRIBUTE_PRINTF_2; +void cbl_internal_error(const char *format_string, ...) + ATTRIBUTE_GCOBOL_DIAG(1, 2); -void cbl_err(const char *format_string, ...); -void cbl_errx(const char *format_string, ...); +void cbl_err(const char *format_string, ...) ATTRIBUTE_GCOBOL_DIAG(1, 2); +void cbl_errx(const char *format_string, ...) ATTRIBUTE_GCOBOL_DIAG(1, 2); bool fisdigit(int c); bool fisspace(int c); diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 4946f87..423fc63 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -9351,7 +9351,6 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx count_exp, rtx val_exp, bool need_zero_guard = false; bool noalign; machine_mode move_mode = VOIDmode; - machine_mode wider_mode; int unroll_factor = 1; /* TODO: Once value ranges are available, fill in proper data. */ unsigned HOST_WIDE_INT min_size = 0; @@ -9427,6 +9426,7 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx count_exp, rtx val_exp, unroll_factor = 1; move_mode = word_mode; + int nunits; switch (alg) { case libcall: @@ -9447,27 +9447,14 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx count_exp, rtx val_exp, case vector_loop: need_zero_guard = true; unroll_factor = 4; - /* Find the widest supported mode. */ - move_mode = word_mode; - while (GET_MODE_WIDER_MODE (move_mode).exists (&wider_mode) - && optab_handler (mov_optab, wider_mode) != CODE_FOR_nothing) - move_mode = wider_mode; - - if (TARGET_AVX256_SPLIT_REGS && GET_MODE_BITSIZE (move_mode) > 128) - move_mode = TImode; - if (TARGET_AVX512_SPLIT_REGS && GET_MODE_BITSIZE (move_mode) > 256) - move_mode = OImode; - - /* Find the corresponding vector mode with the same size as MOVE_MODE. - MOVE_MODE is an integer mode at the moment (SI, DI, TI, etc.). */ - if (GET_MODE_SIZE (move_mode) > GET_MODE_SIZE (word_mode)) - { - int nunits = GET_MODE_SIZE (move_mode) / GET_MODE_SIZE (word_mode); - if (!mode_for_vector (word_mode, nunits).exists (&move_mode) - || optab_handler (mov_optab, move_mode) == CODE_FOR_nothing) - move_mode = word_mode; - } - gcc_assert (optab_handler (mov_optab, move_mode) != CODE_FOR_nothing); + /* Get the vector mode to move MOVE_MAX bytes. */ + nunits = MOVE_MAX / GET_MODE_SIZE (word_mode); + if (nunits > 1) + { + move_mode = mode_for_vector (word_mode, nunits).require (); + gcc_assert (optab_handler (mov_optab, move_mode) + != CODE_FOR_nothing); + } break; case rep_prefix_8_byte: move_mode = DImode; diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 9bf198c..7785329 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -9234,10 +9234,9 @@ ix86_expand_prologue (void) the stack frame saving one cycle of the prologue. However, avoid doing this if we have to probe the stack; at least on x86_64 the stack probe can turn into a call that clobbers a red zone location. */ - else if ((ix86_using_red_zone () + else if (ix86_using_red_zone () && (! TARGET_STACK_PROBE || frame.stack_pointer_offset < CHECK_STACK_LIMIT)) - || crtl->shrink_wrapped_separate) { HOST_WIDE_INT allocate_offset; if (crtl->shrink_wrapped_separate) @@ -9253,11 +9252,6 @@ ix86_expand_prologue (void) ix86_emit_save_regs_using_mov (frame.reg_save_offset); int_registers_saved = true; - - if (ix86_using_red_zone () - && (! TARGET_STACK_PROBE - || frame.stack_pointer_offset < CHECK_STACK_LIMIT)) - cfun->machine->red_zone_used = true; } } @@ -9377,8 +9371,6 @@ ix86_expand_prologue (void) && flag_stack_clash_protection && !ix86_target_stack_probe ()) { - gcc_assert (!crtl->shrink_wrapped_separate); - ix86_adjust_stack_and_probe (allocate, int_registers_saved, false); allocate = 0; } @@ -9389,8 +9381,6 @@ ix86_expand_prologue (void) { const HOST_WIDE_INT probe_interval = get_probe_interval (); - gcc_assert (!crtl->shrink_wrapped_separate); - if (STACK_CHECK_MOVING_SP) { if (crtl->is_leaf @@ -9447,8 +9437,6 @@ ix86_expand_prologue (void) else if (!ix86_target_stack_probe () || frame.stack_pointer_offset < CHECK_STACK_LIMIT) { - gcc_assert (!crtl->shrink_wrapped_separate); - pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-allocate), -1, m->fs.cfa_reg == stack_pointer_rtx); diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 6bd5574..423ef48 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -2438,22 +2438,32 @@ (set_attr "mode" "SI") (set_attr "length_immediate" "0")]) -(define_insn "*mov<mode>_and" +;; Generate shorter "and $0,mem" for -Oz. Split it to "mov $0,mem" +;; otherwise. +(define_insn_and_split "*mov<mode>_and" [(set (match_operand:SWI248 0 "memory_operand" "=m") (match_operand:SWI248 1 "const0_operand")) (clobber (reg:CC FLAGS_REG))] "reload_completed" "and{<imodesuffix>}\t{%1, %0|%0, %1}" + "&& !(optimize_insn_for_size_p () && optimize_size > 1)" + [(set (match_dup 0) (match_dup 1))] + "" [(set_attr "type" "alu1") (set_attr "mode" "<MODE>") (set_attr "length_immediate" "1")]) -(define_insn "*mov<mode>_or" +;; Generate shorter "or $-1,mem" for -Oz. Split it to "mov $-1,mem" +;; otherwise. +(define_insn_and_split "*mov<mode>_or" [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm") (match_operand:SWI248 1 "constm1_operand")) (clobber (reg:CC FLAGS_REG))] "reload_completed" "or{<imodesuffix>}\t{%1, %0|%0, %1}" + "&& !(optimize_insn_for_size_p () && optimize_size > 1)" + [(set (match_dup 0) (match_dup 1))] + "" [(set_attr "type" "alu1") (set_attr "mode" "<MODE>") (set_attr "length_immediate" "1")]) @@ -2958,6 +2968,7 @@ (match_operand:SWI248 1 "const_int_operand"))] "optimize_insn_for_size_p () && optimize_size > 1 && operands[1] != const0_rtx + && operands[1] != constm1_rtx && IN_RANGE (INTVAL (operands[1]), -128, 127) && !ix86_red_zone_used && REGNO (operands[0]) != SP_REG" diff --git a/gcc/config/or1k/or1k.cc b/gcc/config/or1k/or1k.cc index f1c92c6..868df67 100644 --- a/gcc/config/or1k/or1k.cc +++ b/gcc/config/or1k/or1k.cc @@ -1654,6 +1654,63 @@ or1k_rtx_costs (rtx x, machine_mode mode, int outer_code, int /* opno */, #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS or1k_rtx_costs +static bool +or1k_is_cmov_insn (rtx_insn *seq) +{ + rtx_insn *curr_insn = seq; + rtx set = NULL_RTX; + + /* The pattern may start with a simple set with register operands. Skip + through any of those. */ + while (curr_insn) + { + set = single_set (curr_insn); + if (!set + || !REG_P (SET_DEST (set))) + return false; + + /* If it's not a simple reg or immediate break. */ + if (REG_P (SET_SRC (set)) || CONST_INT_P (SET_SRC (set))) + curr_insn = NEXT_INSN (curr_insn); + else + break; + } + + if (!curr_insn) + return false; + + /* The next instruction should be a compare. OpenRISC has many operators used + for comparison so skip and confirm the next is IF_THEN_ELSE. */ + curr_insn = NEXT_INSN (curr_insn); + if (!curr_insn) + return false; + + /* And the last instruction should be an IF_THEN_ELSE. */ + set = single_set (curr_insn); + if (!set + || !REG_P (SET_DEST (set)) + || GET_CODE (SET_SRC (set)) != IF_THEN_ELSE) + return false; + + return !NEXT_INSN (curr_insn); +} + +/* Implement TARGET_NOCE_CONVERSION_PROFITABLE_P. We detect if the conversion + resulted in a l.cmov instruction and if so we consider it more profitable than + branch instructions. */ + +static bool +or1k_noce_conversion_profitable_p (rtx_insn *seq, + struct noce_if_info *if_info) +{ + if (TARGET_CMOV) + return or1k_is_cmov_insn (seq); + + return default_noce_conversion_profitable_p (seq, if_info); +} + +#undef TARGET_NOCE_CONVERSION_PROFITABLE_P +#define TARGET_NOCE_CONVERSION_PROFITABLE_P or1k_noce_conversion_profitable_p /* A subroutine of the atomic operation splitters. Jump to LABEL if COND is true. Mark the jump as unlikely to be taken. */ diff --git a/gcc/config/or1k/or1k.md b/gcc/config/or1k/or1k.md index 627e400..bf71253 100644 --- a/gcc/config/or1k/or1k.md +++ b/gcc/config/or1k/or1k.md @@ -515,6 +515,31 @@ (ne:SI (reg:BI SR_F_REGNUM) (const_int 0)))] "") +;; Allowing "extending" the BImode SR_F to a general register +;; avoids 'convert_mode_scalar' from trying to do subregging +;; which we don't have support for. +;; We require signed and unsigned extend instructions because +;; signed comparisons require signed extention, but for SR_F +;; it doesn't matter. + +(define_expand "zero_extendbisi2_sr_f" + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:BI 1 "sr_f_reg_operand" "")))] + "" +{ + emit_insn(gen_sne_sr_f (operands[0])); + DONE; +}) + +(define_expand "extendbisi2_sr_f" + [(set (match_operand:SI 0 "register_operand" "") + (sign_extend:SI (match_operand:BI 1 "sr_f_reg_operand" "")))] + "" +{ + emit_insn(gen_sne_sr_f (operands[0])); + DONE; +}) + (define_insn_and_split "*scc" [(set (match_operand:SI 0 "register_operand" "=r") (match_operator:SI 1 "equality_comparison_operator" @@ -584,7 +609,7 @@ ;; Branch instructions ;; ------------------------------------------------------------------------- -(define_expand "cbranchsi4" +(define_insn_and_split "cbranchsi4" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" @@ -593,13 +618,27 @@ (label_ref (match_operand 3 "" "")) (pc)))] "" + "#" + "&& 1" + [(const_int 0)] { + rtx label; + + /* Generate *scc */ or1k_expand_compare (operands); + /* Generate *cbranch */ + label = gen_rtx_LABEL_REF (VOIDmode, operands[3]); + emit_jump_insn (gen_rtx_SET (pc_rtx, + gen_rtx_IF_THEN_ELSE (VOIDmode, + operands[0], + label, + pc_rtx))); + DONE; }) ;; Support FP branching -(define_expand "cbranch<F:mode>4" +(define_insn_and_split "cbranch<F:mode>4" [(set (pc) (if_then_else (match_operator 0 "fp_comparison_operator" @@ -608,8 +647,22 @@ (label_ref (match_operand 3 "" "")) (pc)))] "TARGET_HARD_FLOAT" + "#" + "&& 1" + [(const_int 0)] { + rtx label; + + /* Generate *scc */ or1k_expand_compare (operands); + /* Generate *cbranch */ + label = gen_rtx_LABEL_REF (VOIDmode, operands[3]); + emit_jump_insn (gen_rtx_SET (pc_rtx, + gen_rtx_IF_THEN_ELSE (VOIDmode, + operands[0], + label, + pc_rtx))); + DONE; }) (define_insn "*cbranch" diff --git a/gcc/config/or1k/predicates.md b/gcc/config/or1k/predicates.md index 144f4d7..7ccfd09 100644 --- a/gcc/config/or1k/predicates.md +++ b/gcc/config/or1k/predicates.md @@ -60,6 +60,10 @@ (and (match_operand 0 "register_operand") (match_test "TARGET_ROR")))) +(define_predicate "sr_f_reg_operand" + (and (match_operand 0 "register_operand") + (match_test "REGNO (op) == SR_F_REGNUM"))) + (define_predicate "call_insn_operand" (ior (and (match_code "symbol_ref") (match_test "!TARGET_CMODEL_LARGE")) diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def index cff7c77..2096c00 100644 --- a/gcc/config/riscv/riscv-cores.def +++ b/gcc/config/riscv/riscv-cores.def @@ -33,6 +33,7 @@ #define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO) #endif +RISCV_TUNE("generic", generic, generic_tune_info) RISCV_TUNE("rocket", generic, rocket_tune_info) RISCV_TUNE("sifive-3-series", generic, rocket_tune_info) RISCV_TUNE("sifive-5-series", generic, rocket_tune_info) diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index a903de9..ac690df 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -5540,6 +5540,7 @@ expand_vx_binary_vec_dup_vec (rtx op_0, rtx op_1, rtx op_2, case SMAX: case UMAX: case SMIN: + case UMIN: icode = code_for_pred_scalar (code, mode); break; case MINUS: @@ -5577,6 +5578,7 @@ expand_vx_binary_vec_vec_dup (rtx op_0, rtx op_1, rtx op_2, case SMAX: case UMAX: case SMIN: + case UMIN: icode = code_for_pred_scalar (code, mode); break; default: diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index de8bde9..3c1bb74 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -450,6 +450,29 @@ static const struct cpu_vector_cost generic_vector_cost = { &rvv_regmove_vector_cost, /* regmove */ }; +/* Costs to use when optimizing for generic. */ +static const struct riscv_tune_param generic_tune_info = { + {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */ + {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */ + {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */ + {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */ + {COSTS_N_INSNS (33), COSTS_N_INSNS (65)}, /* int_div */ + 1, /* issue_rate */ + 4, /* branch_cost */ + 5, /* memory_cost */ + 8, /* fmv_cost */ + true, /* slow_unaligned_access */ + false, /* vector_unaligned_access */ + false, /* use_divmod_expansion */ + false, /* overlap_op_by_pieces */ + false, /* speculative_sched_vsetvl */ + RISCV_FUSE_NOTHING, /* fusible_ops */ + NULL, /* vector cost */ + NULL, /* function_align */ + NULL, /* jump_align */ + NULL, /* loop_align */ +}; + /* Costs to use when optimizing for rocket. */ static const struct riscv_tune_param rocket_tune_info = { {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */ @@ -814,6 +837,16 @@ void riscv_frame_info::reset(void) arg_pointer_offset = 0; } +/* Check if the mode is twice the size of the XLEN mode. */ + +static bool +riscv_2x_xlen_mode_p (machine_mode mode) +{ + poly_int64 mode_size = GET_MODE_SIZE (mode); + return mode_size.is_constant () + && (mode_size.to_constant () == UNITS_PER_WORD * 2); +} + /* Implement TARGET_MIN_ARITHMETIC_PRECISION. */ static unsigned int @@ -3778,10 +3811,8 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src) return true; } - if (TARGET_ZILSD - && (GET_MODE_UNIT_SIZE (mode) == (UNITS_PER_WORD * 2)) - && ((REG_P (dest) && MEM_P (src)) - || (MEM_P (dest) && REG_P (src))) + if (TARGET_ZILSD && riscv_2x_xlen_mode_p (mode) + && ((REG_P (dest) && MEM_P (src)) || (MEM_P (dest) && REG_P (src))) && can_create_pseudo_p ()) { rtx reg = REG_P (dest) ? dest : src; @@ -3868,7 +3899,7 @@ static int riscv_binary_cost (rtx x, int single_insns, int double_insns) { if (!riscv_v_ext_mode_p (GET_MODE (x)) - && GET_MODE_SIZE (GET_MODE (x)).to_constant () == UNITS_PER_WORD * 2) + && riscv_2x_xlen_mode_p (GET_MODE (x))) return COSTS_N_INSNS (double_insns); return COSTS_N_INSNS (single_insns); } @@ -3981,6 +4012,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN case SMAX: case UMAX: case SMIN: + case UMIN: { rtx op; rtx op_0 = XEXP (x, 0); @@ -4023,10 +4055,41 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN *total = COSTS_N_INSNS (1); return true; } + + /* Register move for XLEN * 2. */ + if (TARGET_ZILSD + && register_operand (SET_SRC (x), GET_MODE (SET_SRC (x))) + && riscv_2x_xlen_mode_p (mode)) + { + /* We still need two instruction for move with ZILSD, + but let minus one cost to let subreg split don't. + TODO: Add riscv_tune_param for this. */ + *total = COSTS_N_INSNS (2) - 1; + return true; + } + + /* Load for XLEN * 2. */ + if (TARGET_ZILSD && MEM_P (SET_SRC (x)) + && riscv_2x_xlen_mode_p (mode)) + { + /* TODO: Add riscv_tune_param for this. */ + *total = COSTS_N_INSNS (1); + return true; + } + riscv_rtx_costs (SET_SRC (x), mode, SET, opno, total, speed); return true; } + /* Store for XLEN * 2. */ + if (TARGET_ZILSD && MEM_P (SET_DEST (x)) && REG_P (SET_SRC (x)) + && riscv_2x_xlen_mode_p (mode)) + { + /* TODO: Add riscv_tune_param for this. */ + *total = COSTS_N_INSNS (1); + return true; + } + /* Otherwise return FALSE indicating we should recurse into both the SET_DEST and SET_SRC combining the cost of both. */ return false; @@ -9974,9 +10037,7 @@ riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode) return false; /* Zilsd require load/store with even-odd reg pair. */ - if (TARGET_ZILSD - && (GET_MODE_UNIT_SIZE (mode) == (UNITS_PER_WORD * 2)) - && ((regno % 2) != 0)) + if (TARGET_ZILSD && riscv_2x_xlen_mode_p (mode) && ((regno % 2) != 0)) return false; if (!GP_REG_P (regno + nregs - 1)) diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 2759a4c..45fa521 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -43,7 +43,7 @@ along with GCC; see the file COPYING3. If not see #endif #ifndef RISCV_TUNE_STRING_DEFAULT -#define RISCV_TUNE_STRING_DEFAULT "rocket" +#define RISCV_TUNE_STRING_DEFAULT "generic" #endif extern const char *riscv_expand_arch (int argc, const char **argv); diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 6cfa926..44ae79c 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -4042,11 +4042,11 @@ ]) (define_code_iterator any_int_binop_no_shift_v_vdup [ - plus minus and ior xor mult div udiv mod umod smax umax smin + plus minus and ior xor mult div udiv mod umod smax umax smin umin ]) (define_code_iterator any_int_binop_no_shift_vdup_v [ - plus minus and ior xor mult smax umax smin + plus minus and ior xor mult smax umax smin umin ]) (define_code_iterator any_int_unop [neg not]) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b233f88..4a86326 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,23 @@ +2025-06-18 Iain Sandoe <iain@sandoe.co.uk> + + PR c++/115908 + PR c++/118074 + PR c++/95615 + * coroutines.cc (coro_frame_refcount_id): New. + (coro_init_identifiers): Initialise coro_frame_refcount_id. + (build_actor_fn): Set up initial_await_resume_called. Handle + decrementing of the frame reference count. Return directly to + the caller if that is non-zero. + (cp_coroutine_transform::wrap_original_function_body): Use a + conditional eh-only cleanup around the initial await expression + to release the body use on exception before initial await + resume. + (cp_coroutine_transform::build_ramp_function): Wrap the called + body in a cleanup that releases a use of the frame when we + return to the ramp. Implement frame, promise and argument copy + destruction via conditional cleanups when the frame use count + is zero. + 2025-06-17 Iain Sandoe <iain@sandoe.co.uk> * coroutines.cc (struct coroutine_info): Update comments. diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index a0d155b..52cc186 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -191,8 +191,87 @@ static bool coro_promise_type_found_p (tree, location_t); just syntactic sugar for a co_await). We defer the analysis and transformation until template expansion is - complete so that we have complete types at that time. */ + complete so that we have complete types at that time. + --------------------------------------------------------------------------- + + Coroutine state, and responsibility for its release. + + As noted above, a coroutine has some state that persists across suspensions. + + The state has two components: + * State that is specified by the standard and persists for the entire + life of the coroutine. + * Local state that is constructed/destructed as scopes in the original + function body are entered/exited. The destruction of local state is + always the responsibility of the body code. + + The persistent state (and the overall storage for the state) must be + managed in two places: + * The ramp function (which allocates and builds this - and can, in some + cases, be responsible for destroying it) + * The re-written function body which can destroy it when that body + completes its final suspend - or when the handle.destroy () is called. + + In all cases the ramp holds responsibility for constructing the standard- + mandated persistent state. + + There are four ways in which the ramp might be re-entered after starting + the function body: + A The body could suspend (one might expect that to be the 'normal' case + for most coroutines). + B The body might complete either synchronously or via continuations. + C An exception might be thrown during the setup of the initial await + expression, before the initial awaiter resumes. + D An exception might be processed by promise.unhandled_exception () and + that, in turn, might re-throw it (or throw something else). In this + case, the coroutine is considered suspended at the final suspension + point. + + Until the ramp return value has been constructed, the ramp is considered + to have a use of the state. + + To manage these interacting conditions we allocate a reference counter + for the frame state. This is initialised to 1 by the ramp as part of its + startup (note that failures/exceptions in the startup code are handled + locally to the ramp). + + When the body returns (either normally, or by exception) the ramp releases + its use. + + Once the rewritten coroutine body is started, the body is considered to + have a use of the frame. This use (potentially) needs to be released if + an exception is thrown from the body. We implement this using an eh-only + cleanup around the initial await and function body. If we have the case + D above, then we do not release the use. + + In case: + + A, typically the ramp would be re-entered with the body holding a use, + and therefore the ramp should not destroy the state. + + B, both the body and ramp will have released their uses, and the ramp + should destroy the state. + + C, we must arrange for the body to release its use, because we require + the ramp to cleanup in this circumstance. + + D is an outlier, since the responsibility for destruction of the state + now rests with the user's code (via a handle.destroy() call). + + NOTE: In the case that the body has never suspended before such an + exception occurs, the only reasonable way for the user code to obtain the + necessary handle is if unhandled_exception() throws the handle or some + object that contains the handle. That is outside of the designs here - + if the user code might need this corner-case, then such provision will + have to be made. + + In the ramp, we implement destruction for the persistent frame state by + means of cleanups. These are run conditionally when the reference count + is 0 signalling that both the body and the ramp have completed. + + In the body, once we pass the final suspend, then we test the use and + delete the state if the use is 0. */ /* The state that we collect during parsing (and template expansion) for a coroutine. */ @@ -347,6 +426,7 @@ static GTY(()) tree coro_resume_index_id; static GTY(()) tree coro_self_handle_id; static GTY(()) tree coro_actor_continue_id; static GTY(()) tree coro_frame_i_a_r_c_id; +static GTY(()) tree coro_frame_refcount_id; /* Create the identifiers used by the coroutines library interfaces and the implementation frame state. */ @@ -384,6 +464,7 @@ coro_init_identifiers () coro_resume_index_id = get_identifier ("_Coro_resume_index"); coro_self_handle_id = get_identifier ("_Coro_self_handle"); coro_actor_continue_id = get_identifier ("_Coro_actor_continue"); + coro_frame_refcount_id = get_identifier ("_Coro_frame_refcount"); } /* Trees we only need to set up once. */ @@ -2598,6 +2679,17 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, /* Now we start building the rewritten function body. */ add_stmt (build_stmt (loc, LABEL_EXPR, actor_begin_label)); + tree i_a_r_c = NULL_TREE; + if (flag_exceptions) + { + i_a_r_c + = coro_build_frame_access_expr (actor_frame, coro_frame_i_a_r_c_id, + false, tf_warning_or_error); + tree m = cp_build_modify_expr (loc, i_a_r_c, NOP_EXPR, + boolean_false_node, tf_warning_or_error); + finish_expr_stmt (m); + } + /* Now we know the real promise, and enough about the frame layout to decide where to put things. */ @@ -2611,8 +2703,29 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, /* Add in our function body with the co_returns rewritten to final form. */ add_stmt (fnbody); - /* Now do the tail of the function; first cleanups. */ - tree r = build_stmt (loc, LABEL_EXPR, del_promise_label); + /* We are done with the frame, but if the ramp still has a hold on it + we should not cleanup. So decrement the refcount and then return to + the ramp if it is > 0. */ + tree coro_frame_refcount + = coro_build_frame_access_expr (actor_frame, coro_frame_refcount_id, + false, tf_warning_or_error); + tree released = build2_loc (loc, MINUS_EXPR, short_unsigned_type_node, + coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 1)); + tree r = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR, released, + tf_warning_or_error); + finish_expr_stmt (r); + tree cond = build2_loc (loc, NE_EXPR, short_unsigned_type_node, + coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 0)); + tree ramp_cu_if = begin_if_stmt (); + finish_if_stmt_cond (cond, ramp_cu_if); + finish_return_stmt (NULL_TREE); + finish_then_clause (ramp_cu_if); + finish_if_stmt (ramp_cu_if); + + /* Otherwise, do the tail of the function; first cleanups. */ + r = build_stmt (loc, LABEL_EXPR, del_promise_label); add_stmt (r); /* Destructors for the things we built explicitly. @@ -2688,10 +2801,6 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, /* We've now rewritten the tree and added the initial and final co_awaits. Now pass over the tree and expand the co_awaits. */ - tree i_a_r_c = NULL_TREE; - if (flag_exceptions) - i_a_r_c = coro_build_frame_access_expr (actor_frame, coro_frame_i_a_r_c_id, - false, tf_warning_or_error); coro_aw_data data = {actor, actor_fp, resume_idx_var, i_a_r_c, del_promise_label, ret_label, @@ -4470,6 +4579,14 @@ cp_coroutine_transform::wrap_original_function_body () var_list = resume_idx_var; add_decl_expr (resume_idx_var); + tree coro_frame_refcount + = coro_build_artificial_var (loc, coro_frame_refcount_id, + short_unsigned_type_node, orig_fn_decl, + NULL_TREE); + DECL_CHAIN (coro_frame_refcount) = var_list; + var_list = coro_frame_refcount; + add_decl_expr (coro_frame_refcount); + /* If the coroutine has a frame that needs to be freed, this will be set by the ramp. */ var = coro_build_artificial_var (loc, coro_frame_needs_free_id, @@ -4478,6 +4595,15 @@ cp_coroutine_transform::wrap_original_function_body () var_list = var; add_decl_expr (var); + /* We consider that the body has a use of the frame once we start to process + the initial suspend expression. (the use might be relinquished if we + encounter an exception before the body is finished). */ + tree body_use + = build2_loc (loc, PLUS_EXPR, short_unsigned_type_node, coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 1)); + body_use = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR, body_use, + tf_warning_or_error); + finish_expr_stmt (body_use); if (flag_exceptions) { /* Build promise.unhandled_exception(); */ @@ -4498,10 +4624,28 @@ cp_coroutine_transform::wrap_original_function_body () tree tcb = build_stmt (loc, TRY_BLOCK, NULL_TREE, NULL_TREE); add_stmt (tcb); TRY_STMTS (tcb) = push_stmt_list (); + /* We need a new scope to handle the cleanup for the ramp use that is + needed for exceptions. */ + tree except_scope = begin_compound_stmt (0); + current_binding_level->artificial = 1; + tree release + = build2_loc (loc, MINUS_EXPR, short_unsigned_type_node, + coro_frame_refcount, build_int_cst (short_unsigned_type_node, 1)); + release = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR, + release, tf_warning_or_error); + /* Once we pass the initial await resume, the cleanup rules on exception + change so that the responsibility lies with the caller. */ + release = build3 (COND_EXPR, void_type_node, i_a_r_c, + build_empty_stmt (loc), release); + push_cleanup (NULL_TREE, release, /*ehonly*/true); /* Add the initial await to the start of the user-authored function. */ finish_expr_stmt (initial_await); + /* End the scope that handles the remove of frame-use on exception. */ + finish_compound_stmt (except_scope); + /* Append the original function body. */ add_stmt (coroutine_body); + if (return_void) add_stmt (return_void); TRY_STMTS (tcb) = pop_stmt_list (TRY_STMTS (tcb)); @@ -4946,31 +5090,18 @@ cp_coroutine_transform::build_ramp_function () just set it true. */ TREE_USED (frame_needs_free) = true; - tree iarc_x = NULL_TREE; - tree coro_before_return = NULL_TREE; - if (flag_exceptions) - { - coro_before_return - = coro_build_and_push_artificial_var (loc, "_Coro_before_return", - boolean_type_node, orig_fn_decl, - boolean_true_node); - iarc_x - = coro_build_and_push_artificial_var_with_dve (loc, - coro_frame_i_a_r_c_id, - boolean_type_node, - orig_fn_decl, - boolean_false_node, - deref_fp); - tree frame_cleanup = push_stmt_list (); - tree do_fr_cleanup - = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, iarc_x); - do_fr_cleanup = build2_loc (loc, TRUTH_ANDIF_EXPR, boolean_type_node, - coro_before_return, do_fr_cleanup); - r = build3 (COND_EXPR, void_type_node, do_fr_cleanup, - delete_frame_call, void_node); - finish_expr_stmt (r); - push_cleanup (coro_fp, pop_stmt_list (frame_cleanup), /*eh_only*/true); - } + tree coro_frame_refcount + = coro_build_and_push_artificial_var_with_dve (loc, coro_frame_refcount_id, + short_unsigned_type_node, + orig_fn_decl, NULL_TREE, + deref_fp); + /* Cleanup if both the ramp and the body have finished. */ + tree cond + = build2_loc (loc, EQ_EXPR, short_unsigned_type_node, coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 0)); + r = build3 (COND_EXPR, void_type_node, cond, delete_frame_call, + build_empty_stmt (loc)); + push_cleanup (coro_fp, r, /*eh_only*/false); /* Put the resumer and destroyer functions in. */ @@ -5045,24 +5176,20 @@ cp_coroutine_transform::build_ramp_function () /* Arrange for parm copies to be cleaned up when an exception is thrown before initial await resume. */ - if (flag_exceptions && !parm.trivial_dtor) + if (!parm.trivial_dtor) { parm.fr_copy_dtor = cxx_maybe_build_cleanup (fld_idx, tf_warning_or_error); if (parm.fr_copy_dtor && parm.fr_copy_dtor != error_mark_node) { param_dtor_list.safe_push (parm.field_id); - tree param_cleanup = push_stmt_list (); - tree do_cleanup - = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, iarc_x); - do_cleanup - = build2_loc (loc, TRUTH_ANDIF_EXPR, boolean_type_node, - coro_before_return, do_cleanup); - r = build3_loc (loc, COND_EXPR, void_type_node, do_cleanup, - parm.fr_copy_dtor, void_node); - finish_expr_stmt (r); - push_cleanup (fld_idx, pop_stmt_list (param_cleanup), - /*eh_only*/true); + cond + = build2_loc (loc, EQ_EXPR, short_unsigned_type_node, + coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 0)); + r = build3_loc (loc, COND_EXPR, void_type_node, cond, + parm.fr_copy_dtor, build_empty_stmt (loc)); + push_cleanup (fld_idx, r, /*eh_only*/false); } } } @@ -5107,22 +5234,16 @@ cp_coroutine_transform::build_ramp_function () finish_expr_stmt (r); } - if (flag_exceptions) + tree promise_dtor = cxx_maybe_build_cleanup (p, tf_warning_or_error); + /* If the promise is live, then run its dtor if that's available. */ + if (promise_dtor && promise_dtor != error_mark_node) { - tree promise_dtor = cxx_maybe_build_cleanup (p, tf_warning_or_error); - /* If the promise is live, then run its dtor if that's available. */ - if (promise_dtor && promise_dtor != error_mark_node) - { - tree promise_cleanup = push_stmt_list (); - tree do_cleanup - = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, iarc_x); - do_cleanup = build2_loc (loc, TRUTH_ANDIF_EXPR, boolean_type_node, - coro_before_return, do_cleanup); - r = build3 (COND_EXPR, void_type_node, do_cleanup, - promise_dtor, void_node); - finish_expr_stmt (r); - push_cleanup (p, pop_stmt_list (promise_cleanup), /*eh_only*/true); - } + cond = build2_loc (loc, EQ_EXPR, short_unsigned_type_node, + coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 0)); + r = build3 (COND_EXPR, void_type_node, cond, promise_dtor, + build_empty_stmt (loc)); + push_cleanup (p, r, /*eh_only*/false); } tree get_ro @@ -5187,16 +5308,22 @@ cp_coroutine_transform::build_ramp_function () push_cleanup (coro_gro, coro_gro_cleanup, /*eh_only*/false); } - /* Start the coroutine body. */ - r = build_call_expr_loc (fn_start, resumer, 1, coro_fp); + /* Start the coroutine body, we now have a use of the frame... */ + r = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR, + build_int_cst (short_unsigned_type_node, 1), + tf_warning_or_error); finish_expr_stmt (r); + /* ... but when we finish we want to release that, and we want to do that + before any of the other cleanups run. */ + tree released + = build2_loc (loc, MINUS_EXPR, short_unsigned_type_node, coro_frame_refcount, + build_int_cst (short_unsigned_type_node, 1)); + released = cp_build_modify_expr (loc, coro_frame_refcount, NOP_EXPR, released, + tf_warning_or_error); + push_cleanup (NULL_TREE, released, /*eh_only*/false); - if (flag_exceptions) - { - r = cp_build_modify_expr (input_location, coro_before_return, NOP_EXPR, - boolean_false_node, tf_warning_or_error); - finish_expr_stmt (r); - } + r = build_call_expr_loc (fn_start, resumer, 1, coro_fp); + finish_expr_stmt (r); /* The ramp is done, we just need the return statement, which we build from the return object we constructed before we called the actor. */ @@ -619,11 +619,21 @@ decimal_real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision) decNumber dn, dn2, dn3; REAL_VALUE_TYPE to; char string[256]; + int scale = 0; decContextDefault (&set, DEC_INIT_DECIMAL128); set.traps = 0; set.round = DEC_ROUND_DOWN; decimal128ToNumber ((const decimal128 *) r->sig, &dn); + if (precision > 64 && decNumberIsFinite (&dn) && dn.exponent > 0) + { + /* libdecNumber doesn't really handle too large integers. + So when precision is large and exponent as well, trim the + exponent and adjust the resulting wide_int by multiplying + it multiple times with powers of ten. */ + scale = dn.exponent; + dn.exponent = 0; + } decNumberToIntegralValue (&dn2, &dn, &set); decNumberZero (&dn3); @@ -633,7 +643,74 @@ decimal_real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision) function. */ decNumberToString (&dn, string); real_from_string (&to, string); - return real_to_integer (&to, fail, precision); + bool failp = false; + wide_int w = real_to_integer (&to, &failp, precision); + if (failp) + *fail = true; + if (scale && !failp) + { + bool isneg = wi::neg_p (w); + if (isneg) + w = -w; + enum wi::overflow_type ovf = wi::OVF_NONE; + unsigned HOST_WIDE_INT pow10s[] = { + HOST_WIDE_INT_UC (10), + HOST_WIDE_INT_UC (100), + HOST_WIDE_INT_UC (1000), + HOST_WIDE_INT_UC (10000), + HOST_WIDE_INT_UC (100000), + HOST_WIDE_INT_UC (1000000), + HOST_WIDE_INT_UC (10000000), + HOST_WIDE_INT_UC (100000000), + HOST_WIDE_INT_UC (1000000000), + HOST_WIDE_INT_UC (10000000000), + HOST_WIDE_INT_UC (100000000000), + HOST_WIDE_INT_UC (1000000000000), + HOST_WIDE_INT_UC (10000000000000), + HOST_WIDE_INT_UC (100000000000000), + HOST_WIDE_INT_UC (1000000000000000), + HOST_WIDE_INT_UC (10000000000000000), + HOST_WIDE_INT_UC (100000000000000000), + HOST_WIDE_INT_UC (1000000000000000000), + HOST_WIDE_INT_UC (10000000000000000000), + }; + int s = scale % 19; + if (s) + { + wide_int wm = wi::uhwi (pow10s[s - 1], w.get_precision ()); + w = wi::umul (w, wm, &ovf); + if (ovf) + scale = 0; + } + scale /= 19; + wide_int wm = wi::uhwi (pow10s[18], w.get_precision ()); + while (scale) + { + if (scale & 1) + { + w = wi::umul (w, wm, &ovf); + if (ovf) + break; + } + scale >>= 1; + if (!scale) + break; + wm = wi::umul (wm, wm, &ovf); + if (ovf) + break; + } + if (ovf) + { + *fail = true; + if (isneg) + return wi::set_bit_in_zero (precision - 1, precision); + else + return ~wi::set_bit_in_zero (precision - 1, precision); + } + if (isneg) + w = -w; + } + return w; } /* Perform the decimal floating point operation described by CODE. diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index e4f3cc2..69c6512 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -10668,7 +10668,7 @@ and @samp{[[omp::sequence(...)]]} in C and C++, GCC needs to be invoked with the @option{-fopenmp} option. This option also arranges for automatic linking of the OpenMP runtime library. -@xref{,,,libgomp,GNU Offloading and Multi Processing Runtime Library}. +@xref{Top,,,libgomp,GNU Offloading and Multi Processing Runtime Library}. @xref{OpenMP and OpenACC Options}, for additional options useful with @option{-fopenmp}. @@ -10690,7 +10690,7 @@ To enable the processing of OpenACC directives @samp{#pragma acc} in C and C++, GCC needs to be invoked with the @option{-fopenacc} option. This option also arranges for automatic linking of the OpenACC runtime library. -@xref{,,,libgomp,GNU Offloading and Multi Processing Runtime Library}. +@xref{Top,,,libgomp,GNU Offloading and Multi Processing Runtime Library}. @xref{OpenMP and OpenACC Options}, for additional options useful with @option{-fopenacc}. diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi index 8bf87a2..ecf147a 100644 --- a/gcc/doc/gcov.texi +++ b/gcc/doc/gcov.texi @@ -1077,7 +1077,7 @@ condition 1 not covered (true) -: 12:@} @end smallexample -@anchor {gcov prime paths example} +@anchor{gcov prime paths example} When you compile with @option{--coverage -fpath-coverage} and use the option @option{-e} your output looks like this: diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 34e35a2..80ee2cd 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -631,6 +631,9 @@ building the documentation without error, but you may still want to install a newer release to get the best appearance and usability of the generated manuals. +Also note that Texinfo older than version 7.1 may throw incorrect build +warnings, though the generated documentation is correct. + @item @TeX{} (any working version) Necessary for running @command{texi2dvi} and @command{texi2pdf}, which diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc index e640329..f4fc92b 100644 --- a/gcc/emit-rtl.cc +++ b/gcc/emit-rtl.cc @@ -975,8 +975,9 @@ validate_subreg (machine_mode omode, machine_mode imode, /* Verify that the offset is representable. */ - /* For hard registers, we already have most of these rules collected in - subreg_offset_representable_p. */ + /* Ensure that subregs of hard registers can be folded. In other words, + the hardware register must be valid in the subreg's outer mode, + and consequently the subreg can be replaced with a hardware register. */ if (reg && REG_P (reg) && HARD_REGISTER_P (reg)) { unsigned int regno = REGNO (reg); @@ -987,7 +988,9 @@ validate_subreg (machine_mode omode, machine_mode imode, else if (!REG_CAN_CHANGE_MODE_P (regno, imode, omode)) return false; - return subreg_offset_representable_p (regno, imode, offset, omode); + /* Pass true to allow_stack_regs because targets like x86 + expect to be able to take subregs of the stack pointer. */ + return simplify_subreg_regno (regno, imode, offset, omode, true) >= 0; } /* Do not allow normal SUBREG with stricter alignment than the inner MEM. diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index fb84921..9a5ffb9 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,18 @@ +2025-06-19 Mikael Morin <mikael@gcc.gnu.org> + + PR fortran/120713 + * trans-array.cc (gfc_trans_deferred_array): Statically + initialize deferred length variable for SAVEd character arrays. + +2025-06-18 Harald Anlauf <anlauf@gmx.de> + + PR fortran/82480 + * check.cc (gfc_check_fstat): Extend checks to INTENT(OUT) arguments. + (gfc_check_fstat_sub): Likewise. + (gfc_check_stat): Likewise. + (gfc_check_stat_sub): Likewise. + * intrinsic.texi: Adjust documentation. + 2025-06-16 Harald Anlauf <anlauf@gmx.de> PR fortran/51961 diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc index c8904df..838d523 100644 --- a/gcc/fortran/check.cc +++ b/gcc/fortran/check.cc @@ -6507,7 +6507,7 @@ gfc_check_fseek_sub (gfc_expr *unit, gfc_expr *offset, gfc_expr *whence, gfc_exp bool -gfc_check_fstat (gfc_expr *unit, gfc_expr *array) +gfc_check_fstat (gfc_expr *unit, gfc_expr *values) { if (!type_check (unit, 0, BT_INTEGER)) return false; @@ -6515,11 +6515,17 @@ gfc_check_fstat (gfc_expr *unit, gfc_expr *array) if (!scalar_check (unit, 0)) return false; - if (!type_check (array, 1, BT_INTEGER) + if (!type_check (values, 1, BT_INTEGER) || !kind_value_check (unit, 0, gfc_default_integer_kind)) return false; - if (!array_check (array, 1)) + if (!array_check (values, 1)) + return false; + + if (!variable_check (values, 1, false)) + return false; + + if (!array_size_check (values, 1, 13)) return false; return true; @@ -6527,19 +6533,9 @@ gfc_check_fstat (gfc_expr *unit, gfc_expr *array) bool -gfc_check_fstat_sub (gfc_expr *unit, gfc_expr *array, gfc_expr *status) +gfc_check_fstat_sub (gfc_expr *unit, gfc_expr *values, gfc_expr *status) { - if (!type_check (unit, 0, BT_INTEGER)) - return false; - - if (!scalar_check (unit, 0)) - return false; - - if (!type_check (array, 1, BT_INTEGER) - || !kind_value_check (array, 1, gfc_default_integer_kind)) - return false; - - if (!array_check (array, 1)) + if (!gfc_check_fstat (unit, values)) return false; if (status == NULL) @@ -6552,6 +6548,9 @@ gfc_check_fstat_sub (gfc_expr *unit, gfc_expr *array, gfc_expr *status) if (!scalar_check (status, 2)) return false; + if (!variable_check (status, 2, false)) + return false; + return true; } @@ -6589,18 +6588,24 @@ gfc_check_ftell_sub (gfc_expr *unit, gfc_expr *offset) bool -gfc_check_stat (gfc_expr *name, gfc_expr *array) +gfc_check_stat (gfc_expr *name, gfc_expr *values) { if (!type_check (name, 0, BT_CHARACTER)) return false; if (!kind_value_check (name, 0, gfc_default_character_kind)) return false; - if (!type_check (array, 1, BT_INTEGER) - || !kind_value_check (array, 1, gfc_default_integer_kind)) + if (!type_check (values, 1, BT_INTEGER) + || !kind_value_check (values, 1, gfc_default_integer_kind)) return false; - if (!array_check (array, 1)) + if (!array_check (values, 1)) + return false; + + if (!variable_check (values, 1, false)) + return false; + + if (!array_size_check (values, 1, 13)) return false; return true; @@ -6608,30 +6613,24 @@ gfc_check_stat (gfc_expr *name, gfc_expr *array) bool -gfc_check_stat_sub (gfc_expr *name, gfc_expr *array, gfc_expr *status) +gfc_check_stat_sub (gfc_expr *name, gfc_expr *values, gfc_expr *status) { - if (!type_check (name, 0, BT_CHARACTER)) - return false; - if (!kind_value_check (name, 0, gfc_default_character_kind)) - return false; - - if (!type_check (array, 1, BT_INTEGER) - || !kind_value_check (array, 1, gfc_default_integer_kind)) - return false; - - if (!array_check (array, 1)) + if (!gfc_check_stat (name, values)) return false; if (status == NULL) return true; if (!type_check (status, 2, BT_INTEGER) - || !kind_value_check (array, 1, gfc_default_integer_kind)) + || !kind_value_check (status, 2, gfc_default_integer_kind)) return false; if (!scalar_check (status, 2)) return false; + if (!variable_check (status, 2, false)) + return false; + return true; } diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index 5831995..3103da3 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -7001,9 +7001,11 @@ Subroutine, function @item @emph{Arguments}: @multitable @columnfractions .15 .70 @item @var{UNIT} @tab An open I/O unit number of type @code{INTEGER}. -@item @var{VALUES} @tab The type shall be @code{INTEGER(4), DIMENSION(13)}. -@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER(4)}. Returns 0 -on success and a system specific error code otherwise. +@item @var{VALUES} @tab The type shall be @code{INTEGER, DIMENSION(13)} +of the default kind. +@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER} +of the default kind. +Returns 0 on success and a system specific error code otherwise. @end multitable @item @emph{Example}: @@ -10306,8 +10308,10 @@ Subroutine, function @multitable @columnfractions .15 .70 @item @var{NAME} @tab The type shall be @code{CHARACTER} of the default kind, a valid path within the file system. -@item @var{VALUES} @tab The type shall be @code{INTEGER(4), DIMENSION(13)}. -@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER(4)}. +@item @var{VALUES} @tab The type shall be @code{INTEGER, DIMENSION(13)} +of the default kind. +@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER} +of the default kind. Returns 0 on success and a system specific error code otherwise. @end multitable @@ -14391,6 +14395,8 @@ The elements that are obtained and stored in the array @code{VALUES}: Not all these elements are relevant on all systems. If an element is not relevant, it is returned as 0. +If the value of an element would overflow the range of default integer, +a -1 is returned instead. This intrinsic is provided in both subroutine and function forms; however, only one form can be used in any given program unit. @@ -14402,9 +14408,11 @@ Subroutine, function @multitable @columnfractions .15 .70 @item @var{NAME} @tab The type shall be @code{CHARACTER}, of the default kind and a valid path within the file system. -@item @var{VALUES} @tab The type shall be @code{INTEGER(4), DIMENSION(13)}. -@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER(4)}. Returns 0 -on success and a system specific error code otherwise. +@item @var{VALUES} @tab The type shall be @code{INTEGER, DIMENSION(13)} +of the default kind. +@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER} +of the default kind. +Returns 0 on success and a system specific error code otherwise. @end multitable @item @emph{Example}: diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 9606131..3d27443 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -12067,8 +12067,16 @@ gfc_trans_deferred_array (gfc_symbol * sym, gfc_wrapped_block * block) && !INTEGER_CST_P (sym->ts.u.cl->backend_decl)) { if (sym->ts.deferred && !sym->ts.u.cl->length && !sym->attr.dummy) - gfc_add_modify (&init, sym->ts.u.cl->backend_decl, - build_zero_cst (TREE_TYPE (sym->ts.u.cl->backend_decl))); + { + tree len_expr = sym->ts.u.cl->backend_decl; + tree init_val = build_zero_cst (TREE_TYPE (len_expr)); + if (VAR_P (len_expr) + && sym->attr.save + && !DECL_INITIAL (len_expr)) + DECL_INITIAL (len_expr) = init_val; + else + gfc_add_modify (&init, len_expr, init_val); + } gfc_conv_string_length (sym->ts.u.cl, NULL, &init); gfc_trans_vla_type_sizes (sym, &init); diff --git a/gcc/function.cc b/gcc/function.cc index a5b245a..a3a74b4 100644 --- a/gcc/function.cc +++ b/gcc/function.cc @@ -2937,7 +2937,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all, if (stack_parm == 0) { HOST_WIDE_INT parm_align - = (STRICT_ALIGNMENT + = ((STRICT_ALIGNMENT || BITS_PER_WORD <= MAX_SUPPORTED_STACK_ALIGNMENT) ? MAX (DECL_ALIGN (parm), BITS_PER_WORD) : DECL_ALIGN (parm)); SET_DECL_ALIGN (parm, parm_align); diff --git a/gcc/prime-paths.cc b/gcc/prime-paths.cc index 838343c..5b626ce 100644 --- a/gcc/prime-paths.cc +++ b/gcc/prime-paths.cc @@ -91,6 +91,8 @@ struct auto_sbitmap_vector /* A silly RAII wrpaper for automatically releasing a vec<vec<int>>. */ struct auto_vec_vec : vec<vec<int>> { + auto_vec_vec () = default; + auto_vec_vec (vec<vec<int>> v) : vec<vec<int>>(v) {} ~auto_vec_vec () { release_vec_vec (*this); } }; @@ -635,7 +637,7 @@ trie::insert_with_suffix (array_slice<const int> path) vec<vec<int>> trie::paths () const { - vec<int> path {}; + auto_vec<int> path {}; vec<vec<int>> all {}; auto iter = paths (path); while (iter.next ()) @@ -1658,8 +1660,8 @@ test_split_components () int nscc = graphds_scc (cfg, NULL); auto_graph ccfg (disconnect_sccs (cfg)); - vec<vec<int>> entries {}; - vec<vec<int>> exits {}; + auto_vec_vec entries {}; + auto_vec_vec exits {}; entries.safe_grow_cleared (nscc); exits.safe_grow_cleared (nscc); @@ -1707,7 +1709,7 @@ test_split_components () because other graph inconsistencies are easier to detect. */ /* Count and check singleton components. */ - vec<int> scc_size {}; + auto_vec<int> scc_size {}; scc_size.safe_grow_cleared (nscc); for (int i = 0; i != cfg->n_vertices; ++i) scc_size[cfg->vertices[i].component]++; @@ -1722,14 +1724,14 @@ test_split_components () /* Manually unroll the loop finding the simple paths starting at the vertices in the SCCs. In this case there is only the one SCC. */ trie ccfg_paths; - simple_paths (ccfg, ccfg_paths, 2); - simple_paths (ccfg, ccfg_paths, 4); - simple_paths (ccfg, ccfg_paths, 5); - simple_paths (ccfg, ccfg_paths, 6); - simple_paths (ccfg, ccfg_paths, 7); - simple_paths (ccfg, ccfg_paths, 9); + auto_vec_vec (simple_paths (ccfg, ccfg_paths, 2)); + auto_vec_vec (simple_paths (ccfg, ccfg_paths, 4)); + auto_vec_vec (simple_paths (ccfg, ccfg_paths, 5)); + auto_vec_vec (simple_paths (ccfg, ccfg_paths, 6)); + auto_vec_vec (simple_paths (ccfg, ccfg_paths, 7)); + auto_vec_vec (simple_paths (ccfg, ccfg_paths, 9)); /* Then in+out of trie. */ - vec<vec<int>> xscc_internal_pp = ccfg_paths.paths (); + auto_vec_vec xscc_internal_pp = ccfg_paths.paths (); trie scc_internal_pp; for (auto &p : xscc_internal_pp) scc_internal_pp.insert_with_suffix (p); @@ -1782,7 +1784,7 @@ test_scc_internal_prime_paths () add_edge (scc, 9, 7); add_edge (scc, 7, 2); - vec<vec<int>> paths = prime_paths (scc, 100); + auto_vec_vec paths = prime_paths (scc, 100); const int p01[] = { 5, 7, 2, 4, 6, 9 }; const int p02[] = { 4, 6, 9, 7, 2, 4 }; const int p03[] = { 2, 4, 6, 9, 7, 2 }; @@ -1806,7 +1808,6 @@ test_scc_internal_prime_paths () ASSERT_TRUE (any_equal_p (p09, paths)); ASSERT_TRUE (any_equal_p (p10, paths)); ASSERT_TRUE (any_equal_p (p11, paths)); - release_vec_vec (paths); } /* Test the entry/exit path helpers for the strongly connected component in @@ -1825,13 +1826,13 @@ test_scc_entry_exit_paths () add_edge (scc, 7, 2); trie scc_internal_trie; - simple_paths (scc, scc_internal_trie, 2); - simple_paths (scc, scc_internal_trie, 4); - simple_paths (scc, scc_internal_trie, 5); - simple_paths (scc, scc_internal_trie, 6); - simple_paths (scc, scc_internal_trie, 7); - simple_paths (scc, scc_internal_trie, 9); - vec<vec<int>> scc_prime_paths = scc_internal_trie.paths (); + auto_vec_vec (simple_paths (scc, scc_internal_trie, 2)); + auto_vec_vec (simple_paths (scc, scc_internal_trie, 4)); + auto_vec_vec (simple_paths (scc, scc_internal_trie, 5)); + auto_vec_vec (simple_paths (scc, scc_internal_trie, 6)); + auto_vec_vec (simple_paths (scc, scc_internal_trie, 7)); + auto_vec_vec (simple_paths (scc, scc_internal_trie, 9)); + auto_vec_vec scc_prime_paths = scc_internal_trie.paths (); trie entry_exits {}; scc_entry_exit_paths (scc_prime_paths, 2, 2, entry_exits); @@ -1867,8 +1868,6 @@ test_scc_entry_exit_paths () ASSERT_EQ (count (entries), 2); ASSERT_TRUE (contains (entries, p07)); ASSERT_TRUE (contains (entries, p08)); - - release_vec_vec (scc_prime_paths); } static void @@ -1893,7 +1892,7 @@ test_complete_prime_paths () for (graph_edge *e = cfg->vertices[i].succ; e; e = e->succ_next) bitmap_set_bit (edges[e->src], e->dest); - vec<trie> ccfg_paths {}; + auto_vec<trie> ccfg_paths {}; ccfg_paths.safe_grow_cleared (6); ccfg_paths[0].insert (array_slice <const int> (ccfg_single + 0, 1)); ccfg_paths[1].insert (array_slice <const int> (ccfg_single + 1, 1)); @@ -1997,7 +1996,7 @@ test_entry_prime_paths () exit_prime_paths.insert (ep03); exit_prime_paths.insert (ep04); - vec<int> sccs = binary_search_scc_map (); + auto_vec<int> sccs = binary_search_scc_map (); trie epp = scc_entry_prime_paths (cfg, scc_entry_paths, complete_prime_paths, @@ -2022,14 +2021,13 @@ test_singleton_path () auto_graph cfg (new_graph (3)); add_edge (cfg, 0, 2); add_edge (cfg, 2, 1); - vec<vec<int>> paths = prime_paths (cfg, 100); + auto_vec_vec paths = prime_paths (cfg, 100); ASSERT_EQ (paths.length (), 1); ASSERT_EQ (paths[0].length (), 3); ASSERT_EQ (paths[0][0], 0); ASSERT_EQ (paths[0][1], 2); ASSERT_EQ (paths[0][2], 1); - release_vec_vec (paths); } void diff --git a/gcc/real.cc b/gcc/real.cc index 95a9332..1f987d4 100644 --- a/gcc/real.cc +++ b/gcc/real.cc @@ -101,7 +101,7 @@ static int do_compare (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int); static void do_fix_trunc (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *); static unsigned long rtd_divmod (REAL_VALUE_TYPE *, REAL_VALUE_TYPE *); -static void decimal_from_integer (REAL_VALUE_TYPE *); +static void decimal_from_integer (REAL_VALUE_TYPE *, int); static void decimal_integer_string (char *, const REAL_VALUE_TYPE *, size_t); @@ -2309,7 +2309,9 @@ real_from_integer (REAL_VALUE_TYPE *r, format_helper fmt, } if (fmt.decimal_p ()) - decimal_from_integer (r); + /* We need at most one decimal digits for each 3 bits of input + precision. */ + decimal_from_integer (r, val_in.get_precision () / 3); if (fmt) real_convert (r, fmt, r); } @@ -2364,12 +2366,21 @@ decimal_integer_string (char *str, const REAL_VALUE_TYPE *r_orig, /* Convert a real with an integral value to decimal float. */ static void -decimal_from_integer (REAL_VALUE_TYPE *r) +decimal_from_integer (REAL_VALUE_TYPE *r, int digits) { char str[256]; - decimal_integer_string (str, r, sizeof (str) - 1); - decimal_real_from_string (r, str); + if (digits <= 256) + { + decimal_integer_string (str, r, sizeof (str) - 1); + decimal_real_from_string (r, str); + } + else + { + char *s = XALLOCAVEC (char, digits); + decimal_integer_string (s, r, digits - 1); + decimal_real_from_string (r, s); + } } /* Returns 10**2**N. */ @@ -2506,7 +2506,8 @@ extern bool subreg_offset_representable_p (unsigned int, machine_mode, poly_uint64, machine_mode); extern unsigned int subreg_regno (const_rtx); extern int simplify_subreg_regno (unsigned int, machine_mode, - poly_uint64, machine_mode); + poly_uint64, machine_mode, + bool allow_stack_regs = false); extern int lowpart_subreg_regno (unsigned int, machine_mode, machine_mode); extern unsigned int subreg_nregs (const_rtx); diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc index 239d669..87332ff 100644 --- a/gcc/rtlanal.cc +++ b/gcc/rtlanal.cc @@ -4245,11 +4245,16 @@ subreg_offset_representable_p (unsigned int xregno, machine_mode xmode, can be simplified. Return -1 if the subreg can't be simplified. - XREGNO is a hard register number. */ + XREGNO is a hard register number. ALLOW_STACK_REGS is true if + we should allow subregs of stack_pointer_rtx, frame_pointer_rtx. + and arg_pointer_rtx (which are normally expected to be the unique + way of referring to their respective registers). */ + int simplify_subreg_regno (unsigned int xregno, machine_mode xmode, - poly_uint64 offset, machine_mode ymode) + poly_uint64 offset, machine_mode ymode, + bool allow_stack_regs) { struct subreg_info info; unsigned int yregno; @@ -4260,20 +4265,23 @@ simplify_subreg_regno (unsigned int xregno, machine_mode xmode, && !REG_CAN_CHANGE_MODE_P (xregno, xmode, ymode)) return -1; - /* We shouldn't simplify stack-related registers. */ - if ((!reload_completed || frame_pointer_needed) - && xregno == FRAME_POINTER_REGNUM) - return -1; + if (!allow_stack_regs) + { + /* We shouldn't simplify stack-related registers. */ + if ((!reload_completed || frame_pointer_needed) + && xregno == FRAME_POINTER_REGNUM) + return -1; - if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM - && xregno == ARG_POINTER_REGNUM) - return -1; + if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM + && xregno == ARG_POINTER_REGNUM) + return -1; - if (xregno == STACK_POINTER_REGNUM - /* We should convert hard stack register in LRA if it is - possible. */ - && ! lra_in_progress) - return -1; + if (xregno == STACK_POINTER_REGNUM + /* We should convert hard stack register in LRA if it is + possible. */ + && ! lra_in_progress) + return -1; + } /* Try to get the register offset. */ subreg_get_info (xregno, xmode, offset, ymode, &info); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 50f7983..32e3a59 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,151 @@ +2025-06-19 Jakub Jelinek <jakub@redhat.com> + + PR target/120689 + * gcc.target/i386/pr120689.c: New test. + +2025-06-19 Mikael Morin <mikael@gcc.gnu.org> + + PR fortran/120713 + * gfortran.dg/save_alloc_character_1.f90: New test. + +2025-06-19 H.J. Lu <hjl.tools@gmail.com> + + PR target/120427 + * gcc.target/i386/cold-attribute-4.c: Compile with -Oz. + * gcc.target/i386/pr120427-1.c: New test. + * gcc.target/i386/pr120427-2.c: Likewise. + * gcc.target/i386/pr120427-3.c: Likewise. + * gcc.target/i386/pr120427-4.c: Likewise. + +2025-06-19 Dongyan Chen <chendongyan@isrc.iscas.ac.cn> + + * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c: New test. + +2025-06-19 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/120631 + * gcc.dg/dfp/bitint-10.c: New test. + * gcc.dg/dfp/pr120631.c: New test. + +2025-06-19 Kito Cheng <kito.cheng@sifive.com> + + * gcc.target/riscv/zilsd-code-gen-split-subreg-1.c: New test. + * gcc.target/riscv/zilsd-code-gen-split-subreg-2.c: New test. + +2025-06-19 Lili Cui <lili.cui@intel.com> + + PR target/120697 + * gcc.target/i386/stack-clash-protection.c: New test. + +2025-06-18 Andrew MacLeod <amacleod@redhat.com> + + * gcc.dg/pr119039-1.c: Add space in search criteria. + +2025-06-18 Iain Sandoe <iain@sandoe.co.uk> + + PR c++/115908 + PR c++/118074 + PR c++/95615 + * g++.dg/coroutines/pr115908.C: Move to... + * g++.dg/coroutines/torture/pr115908.C: ...here. + * g++.dg/coroutines/torture/pr95615-02.C: Move to... + * g++.dg/coroutines/torture/pr95615-01-promise-ctor-throws.C: ...here. + * g++.dg/coroutines/torture/pr95615-03.C: Move to... + * g++.dg/coroutines/torture/pr95615-02-get-return-object-throws.C: ...here. + * g++.dg/coroutines/torture/pr95615-01.C: Move to... + * g++.dg/coroutines/torture/pr95615-03-initial-suspend-throws.C: ...here. + * g++.dg/coroutines/torture/pr95615-04.C: Move to... + * g++.dg/coroutines/torture/pr95615-04-initial-await-ready-throws.C: ...here. + * g++.dg/coroutines/torture/pr95615-05.C: Move to... + * g++.dg/coroutines/torture/pr95615-05-initial-await-suspend-throws.C: ...here. + * g++.dg/coroutines/torture/pr95615.inc: Add more cases and ensure that the + code completes properly when no exceptions are thrown. + * g++.dg/coroutines/torture/pr95615-00-nothing-throws.C: New test. + * g++.dg/coroutines/torture/pr95615-06-initial-await-resume-throws.C: New test. + * g++.dg/coroutines/torture/pr95615-07-body-throws.C: New test. + * g++.dg/coroutines/torture/pr95615-08-initial-suspend-throws-uhe-throws.C: New test. + * g++.dg/coroutines/torture/pr95615-09-body-throws-uhe-throws.C: New test. + +2025-06-18 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/119039 + * gcc.dg/pr119039-2.c: New. + +2025-06-18 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/119039 + * gcc.dg/pr119039-1.c: New. + * gcc.dg/tree-ssa/ssa-dom-thread-7.c: Adjust thread counts. + +2025-06-18 Harald Anlauf <anlauf@gmx.de> + + PR fortran/82480 + * gfortran.dg/stat_3.f90: New test. + +2025-06-18 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/120631 + * gcc.dg/dfp/bitint-9.c: New test. + +2025-06-18 Pan Li <pan2.li@intel.com> + + * gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c: Add asm check + for vmin.vx combine. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c: Ditto. + +2025-06-18 Pan Li <pan2.li@intel.com> + + * gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i16.c: Add asm check. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i32.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i64.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i8.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i16.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i32.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i64.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-2-i8.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i16.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i32.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i64.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx-3-i8.c: Ditto. + * gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h: Add test + helper macros. + * gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h: Add test + data for run test. + * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i16.c: New test. + * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i32.c: New test. + * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i64.c: New test. + * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-i8.c: New test. + * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i16.c: New test. + * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i32.c: New test. + * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i64.c: New test. + * gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-i8.c: New test. + +2025-06-18 Lili Cui <lili.cui@intel.com> + Michael Matz <matz@suse.de> + + * gcc.target/x86_64/abi/callabi/leaf-2.c: Adjust the test. + * gcc.target/i386/interrupt-16.c: Likewise. + * gfortran.dg/guality/arg1.f90: Likewise. + * gcc.target/i386/avx10_2-comibf-1.c: Likewise. + * g++.target/i386/shrink_wrap_separate.C: New test. + * gcc.target/i386/shrink_wrap_separate_check_lea.c: Likewise. + +2025-06-18 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/120661 + * gcc.dg/pr120661-1.c: New. + * gcc.dg/pr120661-2.c: New. + 2025-06-17 Eric Botcazou <ebotcazou@adacore.com> * gnat.dg/specs/aggr8.ads: New test. diff --git a/gcc/testsuite/g++.dg/coroutines/pr115908.C b/gcc/testsuite/g++.dg/coroutines/torture/pr115908.C index a40cece..ff562ef 100644 --- a/gcc/testsuite/g++.dg/coroutines/pr115908.C +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr115908.C @@ -3,13 +3,8 @@ // With the changes to deal with CWG2563 (and PR119916) we now use the // referenced promise in the return expression. It is quite reasonable // for a body implementation to complete before control is returned to -// the ramp - and in that case we would be creating the ramp return object -// from an already-deleted promise object. -// This is recognised to be a poor situation and resolution via a core -// issue is planned. - -// In this test we explicitly trigger the circumstance mentioned above. -// { dg-xfail-run-if "" { *-*-* } } +// the ramp - so we need to ensure that the promise lifetime is extended +// in that case, tested here. #include <coroutine> diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-00-nothing-throws.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-00-nothing-throws.C new file mode 100644 index 0000000..07558f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-00-nothing-throws.C @@ -0,0 +1,5 @@ +// { dg-do run } +// { dg-skip-if "requires hosted libstdc++ for cassert in pr95615.inc" { ! hostedlib } } + +// Check that this completes correctly if nothing throws. +#include "pr95615.inc" diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-02.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-01-promise-ctor-throws.C index 504c8b9..504c8b9 100644 --- a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-02.C +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-01-promise-ctor-throws.C diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-03.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-02-get-return-object-throws.C index 90b6395..90b6395 100644 --- a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-03.C +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-02-get-return-object-throws.C diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-01.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-03-initial-suspend-throws.C index baae030..baae030 100644 --- a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-01.C +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-03-initial-suspend-throws.C diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-04.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-04-initial-await-ready-throws.C index 1b7f89f..1b7f89f 100644 --- a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-04.C +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-04-initial-await-ready-throws.C diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-05.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-05-initial-await-suspend-throws.C index 1d302c8..1d302c8 100644 --- a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-05.C +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-05-initial-await-suspend-throws.C diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-06-initial-await-resume-throws.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-06-initial-await-resume-throws.C new file mode 100644 index 0000000..e57b471 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-06-initial-await-resume-throws.C @@ -0,0 +1,7 @@ +// { dg-do run } +// { dg-skip-if "requires hosted libstdc++ for cassert in pr95615.inc" { ! hostedlib } } + +#define INITIAL_AWAIT_RESUME_THROWS 1 +// This should reach unhandled_exception +#define SHOULD_CALL_UNHANDLED_EXCEPTION 1 +#include "pr95615.inc" diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-07-body-throws.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-07-body-throws.C new file mode 100644 index 0000000..fb10599 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-07-body-throws.C @@ -0,0 +1,7 @@ +// { dg-do run } +// { dg-skip-if "requires hosted libstdc++ for cassert in pr95615.inc" { ! hostedlib } } + +#define BODY_THROWS 1 +// This should reach unhandled_exception +#define SHOULD_CALL_UNHANDLED_EXCEPTION 1 +#include "pr95615.inc" diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-08-initial-suspend-throws-uhe-throws.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-08-initial-suspend-throws-uhe-throws.C new file mode 100644 index 0000000..6dc47bf --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-08-initial-suspend-throws-uhe-throws.C @@ -0,0 +1,8 @@ +// { dg-do run } +// { dg-skip-if "requires hosted libstdc++ for cassert in pr95615.inc" { ! hostedlib } } + +#define INITIAL_SUSPEND_THROWS 1 +// It should be irrelevant that unhandled_exception might throw, so we should +// not call it. +#define UNHANDLED_EXCEPTION_THROWS 1 +#include "pr95615.inc" diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615-09-body-throws-uhe-throws.C b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-09-body-throws-uhe-throws.C new file mode 100644 index 0000000..838b2ba --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615-09-body-throws-uhe-throws.C @@ -0,0 +1,10 @@ +// { dg-do run } +// { dg-skip-if "requires hosted libstdc++ for cassert in pr95615.inc" { ! hostedlib } } + +#define BODY_THROWS 1 +// This should reach unhandled_exception... +#define SHOULD_CALL_UNHANDLED_EXCEPTION 1 +// ... which will throw +#define UNHANDLED_EXCEPTION_THROWS 1 +// and we should cleanup by calling destroy. +#include "pr95615.inc" diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr95615.inc b/gcc/testsuite/g++.dg/coroutines/torture/pr95615.inc index b6f78fb..ab6731d 100644 --- a/gcc/testsuite/g++.dg/coroutines/torture/pr95615.inc +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr95615.inc @@ -1,127 +1,209 @@ -#if __has_include(<coroutine>) #include <coroutine> -#else -#include <experimental/coroutine> -namespace std { - using namespace std::experimental; -} -#endif -#include <cassert> +#include <exception> #include <cstdio> #include <cstdlib> -bool frame_live = false; -bool promise_live = false; - -struct X {}; +#ifndef OUTPUT +# define PRINT(X) +# define PRINTF(...) +#else +//#include <iostream> +# define PRINT(X) puts(X) +//# define PRINT(X) std::cout << (X) << std::endl +# define PRINTF(...) printf(__VA_ARGS__) +#endif +int frame_live = 0; +int promise_live = 0; int Y_live = 0; int task_live = 0; +int unhandled_exception_called = 0; + +struct X {}; struct Y { - Y () { std::puts("Y ()"); Y_live++; } - Y (const Y&) { std::puts("Y (const Y&)"); Y_live++; } - ~Y () { std::puts("~Y ()"); Y_live--; } + Y () { + PRINT("Y ()"); + Y_live++; + } + Y (const Y&) { + PRINT("Y (const Y&)"); + Y_live++; + } + ~Y () { + PRINT("~Y ()"); + --Y_live; + } }; struct task { + struct promise_type; + using coro_handle = std::coroutine_handle<promise_type>; + struct Z { + std::exception_ptr eptr; + coro_handle h; + }; struct promise_type { void* operator new(size_t sz) { - std::puts("operator new()"); - frame_live = true; + PRINT("operator new()"); + frame_live++; return ::operator new(sz); } - void operator delete(void* p, size_t sz) { - std::puts("operator delete"); - frame_live = false; - return ::operator delete(p, sz); + static void operator delete(void* p, size_t sz) { + PRINT("operator delete"); + --frame_live; + ::operator delete(p, sz); } promise_type() { - std::puts("promise_type()"); -#if PROMISE_CTOR_THROWS + PRINT("promise_type()"); +#ifdef PROMISE_CTOR_THROWS throw X{}; #endif promise_live = true; } ~promise_type() { - std::puts("~promise_type()"); - promise_live = false; + PRINT("~promise_type()"); + --promise_live; } struct awaiter { bool await_ready() { -#if INITIAL_AWAIT_READY_THROWS + PRINT("initial await_ready()"); +#ifdef INITIAL_AWAIT_READY_THROWS throw X{}; #endif +// If we are testing the suspend infra, then suspend, otherwise continue +// so that we can test later paths (effectively, suspend_never). +#ifdef INITIAL_AWAIT_SUSPEND_THROWS return false; +#else + return true; +#endif } void await_suspend(std::coroutine_handle<>) { -#if INITIAL_AWAIT_SUSPEND_THROWS +#ifdef INITIAL_AWAIT_SUSPEND_THROWS throw X{}; #endif } void await_resume() { -#if INITIAL_AWAIT_RESUME_THROWS -// this would be caught by unhandled_exception () which is tested -// elsewhere. + PRINT("initial await_resume()"); +#ifdef INITIAL_AWAIT_RESUME_THROWS +// This should be caught by unhandled_exception () throw X{}; #endif } }; awaiter initial_suspend() { -#if INITIAL_SUSPEND_THROWS + PRINT("initial_suspend()"); +#ifdef INITIAL_SUSPEND_THROWS throw X{}; #endif return {}; } task get_return_object() { - std::puts("get_return_object()"); -#if GET_RETURN_OBJECT_THROWS + PRINT("get_return_object()"); +#ifdef GET_RETURN_OBJECT_THROWS throw X{}; #endif return task{}; } - std::suspend_never final_suspend() noexcept { return {}; } - void return_void() noexcept {} - void unhandled_exception() noexcept { - std::puts("unhandled_exception()"); + std::suspend_never final_suspend() noexcept { + PRINT("final_suspend()"); + return {}; + } + void return_void() { + PRINT("return_void()"); + } + void unhandled_exception() { + PRINT("unhandled_exception()"); + unhandled_exception_called++; +#ifdef UNHANDLED_EXCEPTION_THROWS + Z z{std::current_exception(),coro_handle::from_promise(*this)}; + throw z; + //throw coro_handle::from_promise(*this); +#endif } }; + + task() noexcept { + PRINT("task()"); + task_live++; + } + task(task&& t) noexcept { + PRINT("task(task&&)"); + task_live++; + } + ~task() noexcept { + PRINT("~task()"); + task_live--; + } - task() { std::puts("task()"); task_live++; } - ~task() { std::puts("~task()"); task_live--; } - task(task&&) { std::puts("task(task&&)"); task_live++; } }; task f(Y Val __attribute__((__unused__))) { - co_return; + PRINT("f()"); +#ifdef BODY_THROWS + throw X{}; +#endif + co_return; } int main() { - bool failed = false; - Y Val; - try { - f(Val); - } catch (X) { - std::puts("caught X"); - if (task_live) - std::puts("task live"), failed = true; - if (promise_live) - std::puts("promise live"), failed = true; - if (frame_live) - std::puts("frame live"), failed = true; - } - + bool failed = false; + Y Val; + try { + PRINT("try-block-s"); + task tsk = f(Val); + PRINT("try-block-e"); + } catch (X) { + PRINT("caught X"); + } catch (task::Z& z) { + PRINTF("caught Z : %d\n",(bool)z.eptr); + if (z.h.done()) + { + PRINT("done, cleaning up"); + z.h.destroy (); + } + else + PRINT("not done?"); + } catch (std::coroutine_handle<task::promise_type>& h) { + PRINT("caught handle"); + if (h.done()) + { + PRINT("done, cleaning up"); + h.destroy (); + } + else + PRINT("not done?"); + } + + if (task_live) + failed = true, __builtin_printf("task still live\n") ; + if (promise_live) + failed = true, __builtin_printf("promise still live\n"); + if (frame_live) + failed = true, __builtin_printf("frame still live : %d\n", frame_live); if (Y_live != 1) - std::printf("Y live %d\n", Y_live), failed = true; + failed = true, __builtin_printf("Y live count : %d\n", Y_live); +#ifdef SHOULD_CALL_UNHANDLED_EXCEPTION + if (unhandled_exception_called != 1) + failed = true, __builtin_printf("unhandled exception : %d\n", unhandled_exception_called); +#else + if (unhandled_exception_called != 0) + failed = true, __builtin_printf("unhandled exception : %d\n", unhandled_exception_called); +#endif + + __builtin_printf("checking result : %s \n",(failed?"bad":"good")); + + fflush(stdout); if (failed) - abort() ; + __builtin_abort(); } diff --git a/gcc/testsuite/gcc.dg/dfp/bitint-10.c b/gcc/testsuite/gcc.dg/dfp/bitint-10.c new file mode 100644 index 0000000..b48f0ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/bitint-10.c @@ -0,0 +1,49 @@ +/* PR middle-end/120631 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-O2" } */ + +#if __BITINT_MAXWIDTH__ >= 128 +_Decimal128 a = 123456789135792468012345678900000000000.0dl; +_BitInt(128) b = 123456789135792468012345678900000000000wb; +_Decimal64 c = 12345678913579000000000000000000000000.0dd; +_BitInt(127) d = 12345678913579000000000000000000000000wb; +#endif +#if __BITINT_MAXWIDTH__ >= 256 +_Decimal128 m = 1234567891357924680123456789000000000000000000000000000000000000000000000000.0dl; +_BitInt(256) n = 1234567891357924680123456789000000000000000000000000000000000000000000000000wb; +_Decimal64 o = 1234567891357900000000000000000000000000000000000000000000000000000000000000.0dd; +_BitInt(255) p = 1234567891357900000000000000000000000000000000000000000000000000000000000000wb; +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 128 + if (a != b || (_BitInt(128)) a != b || c != d || (_BitInt(127)) c != d) + __builtin_abort (); + _Decimal128 e = 123456789135792468012345678900000000000.0dl; + _BitInt(128) f = 123456789135792468012345678900000000000wb; + _Decimal128 g = 123456789135792468012345678900000000000wb; + _BitInt(128) h = 123456789135792468012345678900000000000.0dl; + _Decimal64 i = 12345678913579000000000000000000000000.0dd; + _BitInt(128) j = 12345678913579000000000000000000000000wb; + _Decimal64 k = 12345678913579000000000000000000000000wb; + _BitInt(128) l = 12345678913579000000000000000000000000.0dd; + if (e != g || f != h || i != k || j != l) + __builtin_abort (); +#endif +#if __BITINT_MAXWIDTH__ >= 256 + if (m != n || (_BitInt(256)) m != n || o != p || (_BitInt(255)) o != p) + __builtin_abort (); + _Decimal128 q = 1234567891357924680123456789000000000000000000000000000000000000000000000000.0dl; + _BitInt(256) r = 1234567891357924680123456789000000000000000000000000000000000000000000000000wb; + _Decimal128 s = 1234567891357924680123456789000000000000000000000000000000000000000000000000wb; + _BitInt(256) t = 1234567891357924680123456789000000000000000000000000000000000000000000000000.0dl; + _Decimal64 u = 1234567891357900000000000000000000000000000000000000000000000000000000000000.0dd; + _BitInt(255) v = 1234567891357900000000000000000000000000000000000000000000000000000000000000wb; + _Decimal64 w = 1234567891357900000000000000000000000000000000000000000000000000000000000000wb; + _BitInt(255) x = 1234567891357900000000000000000000000000000000000000000000000000000000000000.0dd; + if (q != s || r != t || u != w || v != x) + __builtin_abort (); +#endif +} diff --git a/gcc/testsuite/gcc.dg/dfp/bitint-9.c b/gcc/testsuite/gcc.dg/dfp/bitint-9.c new file mode 100644 index 0000000..72155a0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/bitint-9.c @@ -0,0 +1,29 @@ +/* PR middle-end/120631 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-O2" } */ + +#if __BITINT_MAXWIDTH__ >= 2048 +_Decimal128 a = 123456789135792468012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0dl; +_BitInt(2048) b = 123456789135792468012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb; +_Decimal64 c = 123456789135790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0dd; +_BitInt(1536) d = 123456789135790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb; +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 2048 + if (a != b || (_BitInt(2048)) a != b || c != d || (_BitInt(1536)) c != d) + __builtin_abort (); + _Decimal128 e = 123456789135792468012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0dl; + _BitInt(2048) f = 123456789135792468012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb; + _Decimal128 g = 123456789135792468012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb; + _BitInt(2048) h = 123456789135792468012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0dl; + _Decimal64 i = 123456789135790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0dd; + _BitInt(1536) j = 123456789135790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb; + _Decimal64 k = 123456789135790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb; + _BitInt(1536) l = 123456789135790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0dd; + if (e != g || f != h || i != k || j != l) + __builtin_abort (); +#endif +} diff --git a/gcc/testsuite/gcc.dg/dfp/pr120631.c b/gcc/testsuite/gcc.dg/dfp/pr120631.c new file mode 100644 index 0000000..2085ff7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/pr120631.c @@ -0,0 +1,25 @@ +/* PR middle-end/120631 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +_Decimal64 a = 1234567891357900000.0dd; +long long b = 1234567891357900000LL; +_Decimal32 c = 1234567000000000000.0df; +long long d = 1234567000000000000LL; + +int +main () +{ + if (a != b || (long long) a != b || c != d || (long long) c != d) + __builtin_abort (); + _Decimal64 e = 1234567891357900000.0dd; + long long f = 1234567891357900000LL; + _Decimal64 g = 1234567891357900000LL; + long long h = 1234567891357900000.0dd; + _Decimal32 i = 1234567000000000000.0df; + long long j = 1234567000000000000LL; + _Decimal32 k = 1234567000000000000LL; + long long l = 1234567000000000000.0df; + if (e != g || f != h || i != k || j != l) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/pr119039-1.c b/gcc/testsuite/gcc.dg/pr119039-1.c new file mode 100644 index 0000000..f91d5eb --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr119039-1.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +extern void foo (void); +extern void bar (void); +extern void baz (void); + +/* Tests the ability to remove cases that are subranges. */ + +void +test (int i) +{ + if (i < 0 || i > 45) + return; + if (i >= 7 && i <= 8) + return; + + switch (i) + { + case 1: + bar (); + break; + case 7 ... 8: + foo (); + case 14: + baz (); + break; + default: + break; + } +} +/* { dg-final { scan-tree-dump-not "foo " "evrp" } } */ diff --git a/gcc/testsuite/gcc.dg/pr119039-2.c b/gcc/testsuite/gcc.dg/pr119039-2.c new file mode 100644 index 0000000..634b400 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr119039-2.c @@ -0,0 +1,60 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +extern void good (void); +extern void bad (void); + +/* Switch simplification should remove 'case 2:' because 'i' will always + * have its 0th bit set (odd). */ + +void bitmask_elimination_1(int i) +{ + i = i | 1; + + switch (i) + { + case 1: + good (); + break; + + // This case should be removed; + case 2: + bad (); + break; + + case 3: + good (); + break; + + default: + break; + } +} + +/* Switch simplification should remove 'case 20-28:' because 'i' will always + * be a multiple of 16. */ +void bitmask_elimination_2 (int i) +{ + int masked_val = i & 0xF0; // This zeroes out the lower 4 bits of 'i' + + switch (masked_val) + { + case 0: + good (); // Reachable. + break; + + // This entire cased should be removed; + case 20 ... 28: + bad (); + break; + + case 32: + good (); // Reachable. + break; + + default: + good (); + break; + } +} +/* { dg-final { scan-tree-dump-not "bad" "evrp" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pr120654.c b/gcc/testsuite/gcc.dg/torture/pr120654.c new file mode 100644 index 0000000..3819b78 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr120654.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ + +int a, c, e, f, h, j; +long g, k; +void *malloc(long); +void free(void *); +int b(int m) { + if (m || a) + return 1; + return 0.0f; +} +int d(int m, int p2) { return b(m) + m + (1 + p2 + p2); } +int i() { + long l[] = {2, 9, 7, 8, g, g, 9, 0, 2, g}; + e = l[c] << 6; +} +void n() { + long o; + int *p = malloc(sizeof(int)); + k = 1 % j; + for (; i() + f + h; o++) + if (p[d(j + 6, (int)k + 1992695866) + h + f + j + (int)k - 1 + o]) + free(p); +} 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 59891f2..1c2cfa4 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,8 +11,8 @@ 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: 10" "thread2" { target { ! aarch64*-*-* } } } } */ -/* { dg-final { scan-tree-dump "Jumps threaded: 17" "thread2" { target { aarch64*-*-* } } } } */ +/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread2" { target { ! aarch64*-*-* } } } } */ +/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread2" { target { aarch64*-*-* } } } } */ enum STATE { S0=0, diff --git a/gcc/testsuite/gcc.target/i386/cold-attribute-4.c b/gcc/testsuite/gcc.target/i386/cold-attribute-4.c index 37a41e9..e0808c5 100644 --- a/gcc/testsuite/gcc.target/i386/cold-attribute-4.c +++ b/gcc/testsuite/gcc.target/i386/cold-attribute-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2" } */ +/* { dg-options "-Oz" } */ #include <string.h> int diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-1.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-1.c new file mode 100644 index 0000000..d4fe2adc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ +/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ +/* { dg-final { scan-assembler-not "movdqa" } } */ + +char a[2048]; +char b[2048]; +void t (void) +{ + __builtin_memcpy (a, b, 2048); +} diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-2.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-2.c new file mode 100644 index 0000000..9a6fcfd --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ +/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ +/* { dg-final { scan-assembler-not "movdqa" } } */ + +char *a; +char *b; +void t (void) +{ + __builtin_memcpy (a, b, 2048); +} diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-3.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-3.c new file mode 100644 index 0000000..010ac24 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ +/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:-1:align" } */ +/* { dg-final { scan-assembler-not "movdqa" } } */ + +char a[2048]; +char b[2048]; +void t (void) +{ + __builtin_memcpy (a, b, 2048); +} diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-4.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-4.c new file mode 100644 index 0000000..87a58ef --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-4.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ +/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:3000:align,libcall:-1:align" } */ +/* { dg-final { scan-assembler-not "movdqa" } } */ + +char a[2048]; +char b[2048]; +void t (void) +{ + __builtin_memcpy (a, b, 2048); +} diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-5.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-5.c new file mode 100644 index 0000000..19e0600 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-5.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -mprefer-vector-width=128 -mmemcpy-strategy=vector_loop:2048:noalign,libcall:-1:noalign" } */ + +#define SIZE (16 + 1) * 16 + +char dest[SIZE]; +char src[SIZE]; + +void +foo (void) +{ + __builtin_memcpy (dest, src, SIZE); +} + +/* { dg-final { scan-assembler-times "vmovdqa\[ \t]\+\[^\n\r]*%xmm\[0-9\]\+" 10 } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-pr120708-6.c b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-6.c new file mode 100644 index 0000000..17b101f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memcpy-pr120708-6.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -mprefer-vector-width=256 -mmemcpy-strategy=vector_loop:2048:noalign,libcall:-1:noalign" } */ + +#define SIZE (16 + 1) * 32 + +char dest[SIZE]; +char src[SIZE]; + +void +foo (void) +{ + __builtin_memcpy (dest, src, SIZE); +} + +/* { dg-final { scan-assembler-times "vmovdqa\[ \t]\+\[^\n\r]*%ymm\[0-9\]\+" 10 } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c b/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c index 6ac80c9..b298673 100644 --- a/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c +++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ -/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ -/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:-1:align" } */ +/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -mmemcpy-strategy=vector_loop:-1:align" } */ /* { dg-final { scan-assembler-times "movdqa" 8 } } */ char a[2048]; diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c b/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c index c103896..18e260b 100644 --- a/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c +++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ -/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ -/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:3000:align,libcall:-1:align" } */ +/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -mmemcpy-strategy=vector_loop:3000:align,libcall:-1:align" } */ /* { dg-final { scan-assembler-times "movdqa" 8 } } */ char a[2048]; diff --git a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c index 93f428a..cec8c90 100644 --- a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c +++ b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ -/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ -/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ +/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -minline-all-stringops -mstringop-strategy=vector_loop" } */ /* { dg-final { scan-assembler-times "movdqa" 8 } } */ char a[2048]; diff --git a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c index ab23540..314eb3d 100644 --- a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c +++ b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c @@ -1,7 +1,6 @@ /* { dg-do compile } */ -/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ -/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ -/* { dg-final { scan-assembler-times "movdqa" 4} } */ +/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -minline-all-stringops -mstringop-strategy=vector_loop" } */ +/* { dg-final { scan-assembler-times "movdqa" 4 } } */ char *a; char *b; diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120708-1.c b/gcc/testsuite/gcc.target/i386/memset-pr120708-1.c new file mode 100644 index 0000000..fba0588 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120708-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -mprefer-vector-width=128 -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 254); +} + +/* { dg-final { scan-assembler "vmovdqu\[ \t]\+%xmm\[0-9\]+, \\(\[^\n\r]*\\)" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-pr120708-2.c b/gcc/testsuite/gcc.target/i386/memset-pr120708-2.c new file mode 100644 index 0000000..d9a3e7e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/memset-pr120708-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64-v4 -mprefer-vector-width=256 -mmemset-strategy=vector_loop:256:noalign,libcall:-1:noalign" } */ + +void +foo (char *dest) +{ + __builtin_memset (dest, 0, 254); +} + +/* { dg-final { scan-assembler "vmovdqu\[ \t]\+%ymm\[0-9\]+, \\(\[^\n\r]*\\)" } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c b/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c index d6fdc98..5bb30a8 100644 --- a/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c +++ b/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ -/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ -/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ +/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -minline-all-stringops -mstringop-strategy=vector_loop" } */ /* { dg-final { scan-assembler-times "movdqa" 4 } } */ char a[2048]; diff --git a/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c b/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c index bce8be0..6e31070 100644 --- a/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c +++ b/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ -/* { dg-skip-if "" { *-*-* } { "-march=*" } { "-march=atom" } } */ -/* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ +/* { dg-options "-O2 -mno-avx -msse2 -mtune=generic -mtune-ctrl=^sse_typeless_stores -mstringop-strategy=vector_loop" } */ /* { dg-final { scan-assembler-times "movdqa" 4} } */ char *a; diff --git a/gcc/testsuite/gcc.target/i386/pr120427-1.c b/gcc/testsuite/gcc.target/i386/pr120427-1.c new file mode 100644 index 0000000..7f1690e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120427-1.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=sapphirerapids" } */ +/* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]+\\\$0, \[0-9\]*\\(" } } */ + +struct __pthread_mutex_s +{ + int __lock; + unsigned int __count; + int __owner; + unsigned int __nusers; + int __kind; + short __spins; + short __elision; + void *p[2]; +}; +typedef union +{ + struct __pthread_mutex_s __data; + char __size[40]; + long int __align; +} pthread_mutex_t; +typedef struct { pthread_mutex_t mutex; } __rtld_lock_recursive_t; +void +foo (__rtld_lock_recursive_t *lock, int i) +{ + lock[i] = (__rtld_lock_recursive_t) {{ { 0, 0, 0, 0, 1, + 0, 0, { ((void *)0) , ((void *)0) } } }}; +} diff --git a/gcc/testsuite/gcc.target/i386/pr120427-2.c b/gcc/testsuite/gcc.target/i386/pr120427-2.c new file mode 100644 index 0000000..a380c12 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120427-2.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=sapphirerapids" } */ +/* { dg-final { scan-assembler-not "or\[lq\]?\[\\t \]+\\\$-1, \[0-9\]*\\(" } } */ + +struct __pthread_mutex_s +{ + int __lock; + unsigned int __count; + int __owner; + unsigned int __nusers; + int __kind; + short __spins; + short __elision; + void *p[2]; +}; +typedef union +{ + struct __pthread_mutex_s __data; + char __size[40]; + long int __align; +} pthread_mutex_t; +typedef struct { pthread_mutex_t mutex; } __rtld_lock_recursive_t; +void +foo (__rtld_lock_recursive_t *lock, int i) +{ + lock[i] = (__rtld_lock_recursive_t) {{ { -1, -1, -1, -1, 1, + -1, -1, { ((void *)-1) , ((void *)-1) } } }}; +} diff --git a/gcc/testsuite/gcc.target/i386/pr120427-3.c b/gcc/testsuite/gcc.target/i386/pr120427-3.c new file mode 100644 index 0000000..951cb1f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120427-3.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); +typedef UDItype __attribute__ ((__may_alias__)) bar_t; + +static inline __attribute__((__always_inline__)) SItype +bar (const bar_t **p, SItype prec) +{ + bar_t mslimb = 0; + SItype i = 20; + SItype n = ((USItype) prec) % 4; + if (n) + { + prec -= n; + if (prec == 0) + return 1; + mslimb = (*p)[i]; + } + while (mslimb == 0) + { + prec -= 4; + if (prec == 0) + return 1; + --i; + mslimb = (*p)[i]; + } + return prec; +} +UDItype +foo (const bar_t *i, SItype iprec) +{ + iprec = bar (&i, iprec); + USItype aiprec = iprec < 0 ? -iprec : iprec; + bar_t msb = *i; + UDItype mantissa = 0; + if (aiprec % 4) + msb &= ((bar_t) 1 << aiprec) - 1; + if (aiprec >= 54) + mantissa = (UDItype) msb << 32; + + return (mantissa ^ (UDItype) 0x20000000000000); +} diff --git a/gcc/testsuite/gcc.target/i386/pr120427-4.c b/gcc/testsuite/gcc.target/i386/pr120427-4.c new file mode 100644 index 0000000..2b453b7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120427-4.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include "cold-attribute-4.c" + +/* { dg-final { scan-assembler "movl" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr120689.c b/gcc/testsuite/gcc.target/i386/pr120689.c new file mode 100644 index 0000000..cd10cdb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr120689.c @@ -0,0 +1,17 @@ +/* PR target/120689 */ +/* { dg-do compile { target lp64 } } */ +/* { dg-options "-O2 -mtune=generic -fno-stack-protector -masm=att" } */ +/* { dg-final { scan-assembler-not "\t\(movzbl\|shrl\|salq\|orq\)\t" } } */ + +struct S { char a, b, c; }; + +[[gnu::noipa]] +void foo (struct S x, struct S y, struct S z) +{ +} + +void +bar (struct S x, struct S y, struct S z) +{ + [[gnu::musttail]] return foo (x, y, z); +} diff --git a/gcc/testsuite/gcc.target/i386/stack-clash-protection.c b/gcc/testsuite/gcc.target/i386/stack-clash-protection.c new file mode 100644 index 0000000..5be28cb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/stack-clash-protection.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fstack-clash-protection" } */ + +int flag; +void open(); +int getChar(); +typedef enum { QUOTE } CharType; +typedef enum { UNQ } State; +CharType getCharType(); +void expand() { + open(); + if (flag) + return; + int ch = getChar(); + State nextState = getCharType(); + if (nextState) + while (ch) + ; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u16.c index e06829d..bcfd514 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u16.c @@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-times {vdivu.vx} 1 } } */ /* { dg-final { scan-assembler-times {vremu.vx} 1 } } */ /* { dg-final { scan-assembler-times {vmaxu.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vminu.vx} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u32.c index 05fb829..b9a6a28 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u32.c @@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-times {vdivu.vx} 1 } } */ /* { dg-final { scan-assembler-times {vremu.vx} 1 } } */ /* { dg-final { scan-assembler-times {vmaxu.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vminu.vx} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c index 4681f36..abb5e5e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c @@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-times {vdivu.vx} 1 } } */ /* { dg-final { scan-assembler-times {vremu.vx} 1 } } */ /* { dg-final { scan-assembler-times {vmaxu.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vminu.vx} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c index 9b4404f..50065d0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c @@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-times {vdivu.vx} 1 } } */ /* { dg-final { scan-assembler-times {vremu.vx} 1 } } */ /* { dg-final { scan-assembler-times {vmaxu.vx} 2 } } */ +/* { dg-final { scan-assembler-times {vminu.vx} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u16.c index ec1b7d9..c03560a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u16.c @@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vdivu.vx} } } */ /* { dg-final { scan-assembler-not {vremu.vx} } } */ /* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u32.c index 40ef107..70fc262 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u32.c @@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vdivu.vx} } } */ /* { dg-final { scan-assembler-not {vremu.vx} } } */ /* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u64.c index abf04d1..a368c96 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u64.c @@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vdivu.vx} } } */ /* { dg-final { scan-assembler-not {vremu.vx} } } */ /* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u8.c index 400fc3c..581da35 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-2-u8.c @@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vdivu.vx} } } */ /* { dg-final { scan-assembler-not {vremu.vx} } } */ /* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u16.c index e6d5014..0620953 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u16.c @@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vdivu.vx} } } */ /* { dg-final { scan-assembler-not {vremu.vx} } } */ /* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u32.c index 4560862..0aca5b9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u32.c @@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vdivu.vx} } } */ /* { dg-final { scan-assembler-not {vremu.vx} } } */ /* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u64.c index 189d554..4dd8f1a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u64.c @@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vdivu.vx} } } */ /* { dg-final { scan-assembler-not {vremu.vx} } } */ /* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u8.c index 6a1905e..1508ff3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-3-u8.c @@ -16,3 +16,4 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-not {vdivu.vx} } } */ /* { dg-final { scan-assembler-not {vremu.vx} } } */ /* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c index 5d684e6..199f8a7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i16.c @@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vdiv.vx} } } */ /* { dg-final { scan-assembler {vrem.vx} } } */ /* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c index 6c086d2..392f4fe 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i32.c @@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vdiv.vx} } } */ /* { dg-final { scan-assembler {vrem.vx} } } */ /* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c index 0abae20..d22c387 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i64.c @@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler {vdiv.vx} } } */ /* { dg-final { scan-assembler {vrem.vx} } } */ /* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c index d2955b8..9a832a2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-i8.c @@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vdiv.vx} } } */ /* { dg-final { scan-assembler {vrem.vx} } } */ /* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c index bee4171..b621643 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c @@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vdivu.vx} } } */ /* { dg-final { scan-assembler {vremu.vx} } } */ /* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c index 376f1c6..741a749 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c @@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vdivu.vx} } } */ /* { dg-final { scan-assembler {vremu.vx} } } */ /* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c index 034f50d..70375b1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c @@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler {vdivu.vx} } } */ /* { dg-final { scan-assembler {vremu.vx} } } */ /* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c index cfb1ad1..b1c22b3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c @@ -15,6 +15,7 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -25,3 +26,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vdivu.vx} } } */ /* { dg-final { scan-assembler {vremu.vx} } } */ /* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c index c42c58e..f15fec5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i16.c @@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vdiv.vx} } } */ /* { dg-final { scan-assembler {vrem.vx} } } */ /* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c index a6d1ad0..8d21c47 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i32.c @@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vdiv.vx} } } */ /* { dg-final { scan-assembler {vrem.vx} } } */ /* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c index ea9c526..0660000 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i64.c @@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler {vdiv.vx} } } */ /* { dg-final { scan-assembler {vrem.vx} } } */ /* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c index d1212ea..ce33461 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-i8.c @@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vdiv.vx} } } */ /* { dg-final { scan-assembler {vrem.vx} } } */ /* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c index 4793fdf..399045b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c @@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vdivu.vx} } } */ /* { dg-final { scan-assembler {vremu.vx} } } */ /* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c index daf2501..f3a2fcb 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c @@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vdivu.vx} } } */ /* { dg-final { scan-assembler {vremu.vx} } } */ /* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c index b4fc5c1..d83acaa 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c @@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler {vdivu.vx} } } */ /* { dg-final { scan-assembler {vremu.vx} } } */ /* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c index ceb6e37..b629bc9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c @@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vdivu.vx} } } */ /* { dg-final { scan-assembler {vremu.vx} } } */ /* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c index 30e38f7..3c9afdd 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i16.c @@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vdiv.vx} } } */ /* { dg-final { scan-assembler {vrem.vx} } } */ /* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c index f0b6bcd..b80a6b3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i32.c @@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vdiv.vx} } } */ /* { dg-final { scan-assembler {vrem.vx} } } */ /* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c index ef168ac..15bfe60 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i64.c @@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler-not {vdiv.vx} } } */ /* { dg-final { scan-assembler-not {vrem.vx} } } */ /* { dg-final { scan-assembler-not {vmax.vx} } } */ +/* { dg-final { scan-assembler-not {vmin.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c index 9977ff3..4d529fe 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-i8.c @@ -16,6 +16,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -27,3 +29,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vdiv.vx} } } */ /* { dg-final { scan-assembler {vrem.vx} } } */ /* { dg-final { scan-assembler {vmax.vx} } } */ +/* { dg-final { scan-assembler {vmin.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c index aee9f12..93e2bf2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c @@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vdivu.vx} } } */ /* { dg-final { scan-assembler {vremu.vx} } } */ /* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c index df48fc4..52336ba 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c @@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X4) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X4) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X4) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X4) /* { dg-final { scan-assembler {vdivu.vx} } } */ /* { dg-final { scan-assembler {vremu.vx} } } */ /* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c index 166cc7d..91be71d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c @@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler-not {vadd.vx} } } */ /* { dg-final { scan-assembler-not {vsub.vx} } } */ @@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY) /* { dg-final { scan-assembler-not {vdivu.vx} } } */ /* { dg-final { scan-assembler-not {vremu.vx} } } */ /* { dg-final { scan-assembler-not {vmaxu.vx} } } */ +/* { dg-final { scan-assembler-not {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c index f19cbdc..4afc04d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c @@ -15,6 +15,8 @@ DEF_VX_BINARY_CASE_1_WRAP(T, /, div, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_1_WRAP(T, %, rem, VX_BINARY_BODY_X16) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_0_WARP(T), max, VX_BINARY_FUNC_BODY_X8) DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_0_WARP(T), min, VX_BINARY_FUNC_BODY_X8) +DEF_VX_BINARY_CASE_3_WRAP(T, MIN_FUNC_1_WARP(T), min, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vadd.vx} } } */ /* { dg-final { scan-assembler {vsub.vx} } } */ @@ -25,3 +27,4 @@ DEF_VX_BINARY_CASE_3_WRAP(T, MAX_FUNC_1_WARP(T), max, VX_BINARY_FUNC_BODY_X8) /* { dg-final { scan-assembler {vdivu.vx} } } */ /* { dg-final { scan-assembler {vremu.vx} } } */ /* { dg-final { scan-assembler {vmaxu.vx} } } */ +/* { dg-final { scan-assembler {vminu.vx} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h index 6a4d948..f47586b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h @@ -191,6 +191,16 @@ DEF_MIN_1(int16_t) DEF_MIN_1(int32_t) DEF_MIN_1(int64_t) +DEF_MIN_0(uint8_t) +DEF_MIN_0(uint16_t) +DEF_MIN_0(uint32_t) +DEF_MIN_0(uint64_t) + +DEF_MIN_1(uint8_t) +DEF_MIN_1(uint16_t) +DEF_MIN_1(uint32_t) +DEF_MIN_1(uint64_t) + #define MIN_FUNC_0(T) test_##T##_min_0 #define MIN_FUNC_0_WARP(T) MIN_FUNC_0(T) @@ -285,6 +295,8 @@ test_vx_binary_##NAME##_##FUNC##_##T##_case_3 (T * restrict out, \ DEF_VX_BINARY_CASE_0_WRAP(T, /, div) \ DEF_VX_BINARY_CASE_0_WRAP(T, %, rem) \ DEF_VX_BINARY_CASE_2_WRAP(T, MAX_FUNC_0_WARP(T), max) \ - DEF_VX_BINARY_CASE_2_WRAP(T, MAX_FUNC_1_WARP(T), max) + DEF_VX_BINARY_CASE_2_WRAP(T, MAX_FUNC_1_WARP(T), max) \ + DEF_VX_BINARY_CASE_2_WRAP(T, MIN_FUNC_0_WARP(T), min) \ + DEF_VX_BINARY_CASE_2_WRAP(T, MIN_FUNC_1_WARP(T), min) #endif diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h index 7f4d2f5..9666301 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h @@ -3926,4 +3926,200 @@ int64_t TEST_BINARY_DATA(int64_t, min)[][3][N] = }, }; +uint8_t TEST_BINARY_DATA(uint8_t, min)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, + { + { 127 }, + { + 127, 127, 127, 127, + 128, 128, 128, 128, + 255, 255, 255, 255, + 1, 1, 1, 1, + }, + { + 127, 127, 127, 127, + 127, 127, 127, 127, + 127, 127, 127, 127, + 1, 1, 1, 1, + }, + }, + { + { 254 }, + { + 128, 128, 128, 128, + 255, 255, 255, 255, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + { + 128, 128, 128, 128, + 254, 254, 254, 254, + 127, 127, 127, 127, + 2, 2, 2, 2, + }, + }, +}; + +uint16_t TEST_BINARY_DATA(uint16_t, min)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, + { + { 32767 }, + { + 32767, 32767, 32767, 32767, + 32768, 32768, 32768, 32768, + 65535, 65535, 65535, 65535, + 1, 1, 1, 1, + }, + { + 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, + 1, 1, 1, 1, + }, + }, + { + { 65534 }, + { + 32768, 32768, 32768, 32768, + 65535, 65535, 65535, 65535, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + { + 32768, 32768, 32768, 32768, + 65534, 65534, 65534, 65534, + 32767, 32767, 32767, 32767, + 2, 2, 2, 2, + }, + }, +}; + +uint32_t TEST_BINARY_DATA(uint32_t, min)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, + { + { 2147483647 }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967295, 4294967295, 4294967295, 4294967295, + 1, 1, 1, 1, + }, + { + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483647, 2147483647, 2147483647, 2147483647, + 2147483647, 2147483647, 2147483647, 2147483647, + 1, 1, 1, 1, + }, + }, + { + { 4294967294 }, + { + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967295, 4294967295, 4294967295, 4294967295, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + { + 2147483648, 2147483648, 2147483648, 2147483648, + 4294967294, 4294967294, 4294967294, 4294967294, + 2147483647, 2147483647, 2147483647, 2147483647, + 2, 2, 2, 2, + }, + }, +}; + +uint64_t TEST_BINARY_DATA(uint64_t, min)[][3][N] = +{ + { + { 0 }, + { + 2, 2, 2, 2, + 1, 1, 1, 1, + 0, 0, 0, 0, + 4, 4, 4, 4, + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + }, + { + { 9223372036854775807ull }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 1, 1, 1, 1, + }, + { + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 1, 1, 1, 1, + }, + }, + { + { 18446744073709551614ull }, + { + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, 18446744073709551615ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 2, 2, 2, 2, + }, + { + 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, 9223372036854775808ull, + 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, 18446744073709551614ull, + 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, 9223372036854775807ull, + 2, 2, 2, 2, + }, + }, +}; + #endif diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u16.c new file mode 100644 index 0000000..5295bb8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint16_t +#define NAME min +#define FUNC MIN_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u32.c new file mode 100644 index 0000000..1e09610 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint32_t +#define NAME min +#define FUNC MIN_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u64.c new file mode 100644 index 0000000..ed757e6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint64_t +#define NAME min +#define FUNC MIN_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u8.c new file mode 100644 index 0000000..dd4b93a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-1-u8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint8_t +#define NAME min +#define FUNC MIN_FUNC_0_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u16.c new file mode 100644 index 0000000..5e450d85 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u16.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint16_t +#define NAME min +#define FUNC MIN_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u32.c new file mode 100644 index 0000000..45bfd12 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint32_t +#define NAME min +#define FUNC MIN_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u64.c new file mode 100644 index 0000000..46f0031 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u64.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint64_t +#define NAME min +#define FUNC MIN_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u8.c new file mode 100644 index 0000000..971404b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx_vmin-run-2-u8.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 --param=gpr2vr-cost=0" } */ + +#include "vx_binary.h" +#include "vx_binary_data.h" + +#define T uint8_t +#define NAME min +#define FUNC MIN_FUNC_1_WARP(T) +#define TEST_DATA TEST_BINARY_DATA_WRAP(T, NAME) + +DEF_VX_BINARY_CASE_2_WRAP(T, FUNC, NAME) + +#define TEST_RUN(T, NAME, out, in, x, n) \ + RUN_VX_BINARY_CASE_2_WRAP(T, NAME, FUNC, out, in, x, n) + +#include "vx_binary_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-37.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-37.c index cd3e961..9bade06 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-37.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-37.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2 -fno-tree-vectorize" } */ +/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2 -fno-tree-vectorize -mtune=rocket" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c index d7f6d18..321eb3b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize" } */ +/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -mtune=rocket" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c index 1354c5e..29dcfef 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize" } */ +/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -mtune=rocket" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c index 6366dd9..8b6299e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize" } */ +/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -mtune=rocket" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c index bbff028..3b836f9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize" } */ +/* { dg-options "-mrvv-vector-bits=scalable -march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -mtune=rocket" } */ #include "riscv_vector.h" diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c new file mode 100644 index 0000000..1ad1b77 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mtune=generic" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mtune=generic" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" "-O3" } } */ + +#define N 10000 + +int primitiveSemantics_compare_reg_reg_return_reg_reg_00(int *a, int min_v) +{ + int last = 0; + + for (int i = 0; i < N; i++) + { + if (a[i] < min_v) + last = a[i]; + } + return last; +} + +/* { dg-final { scan-assembler-times {\mczero\.nez\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mczero\.eqz\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-1.c b/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-1.c new file mode 100644 index 0000000..3602626 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_zilsd -mabi=ilp32" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +long long y; +long long foo(long long x) +{ + return y + x; +} + +/* { dg-final { scan-assembler-times "ld\t" 1 } } */ +/* { dg-final { scan-assembler-not "lw\t" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-2.c b/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-2.c new file mode 100644 index 0000000..3adcd21 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zilsd-code-gen-split-subreg-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i_zilsd -mabi=ilp32" } */ + +long long y; +long long foo(long long x) +{ + return y >> x; +} +/* TODO: We should not split that 64 bit load into two 32 bit load if we have + zilsd, but we split that during the expand time, so it's hard to fix via cost + model turning, we could either fix that for expander, or...combine those two + 32 bit load back later. */ +/* { dg-final { scan-assembler-times "ld\t" 1 { xfail riscv*-*-* } } } */ + +/* Os and Oz will use libcall, so the 64 bit load won't be split. */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Oz" } } */ diff --git a/gcc/testsuite/gfortran.dg/save_alloc_character_1.f90 b/gcc/testsuite/gfortran.dg/save_alloc_character_1.f90 new file mode 100644 index 0000000..e26919f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/save_alloc_character_1.f90 @@ -0,0 +1,23 @@ +! { dg-do run } +! +! PR fortran/120713 +! Check that the length variable of SAVEd allocatable character arrays are +! not initialized at function entry. + +program p + implicit none + call s(1) + call s(2) +contains + subroutine s(i) + integer, intent(in) :: i + character(len=:), allocatable, save :: a(:) + integer :: j + if (i == 1) then + allocate(a, source= [ ('x' // achar(ichar('0') + j), j=1,7) ]) + else + if (len(a) /= 2) error stop 1 + if (any(a /= ['x1','x2','x3','x4','x5','x6','x7'])) error stop 2 + end if + end subroutine s +end program p diff --git a/gcc/testsuite/gfortran.dg/stat_3.f90 b/gcc/testsuite/gfortran.dg/stat_3.f90 new file mode 100644 index 0000000..93ec183 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/stat_3.f90 @@ -0,0 +1,46 @@ +! { dg-do compile } +! PR fortran/82480 - checking of arguments to STAT/LSTAT/FSTAT + +subroutine sub1 () + integer, parameter :: ik = kind(1) + integer(ik) :: buff12(12) + integer(ik) :: buff13(13) + integer(ik) :: unit = 10 + integer(ik) :: ierr + character(len=64) :: name = "/etc/passwd" + ierr = stat (name, values= buff12) ! { dg-error "too small" } + ierr = stat (name, values= buff13) + ierr = lstat (name, values= buff12) ! { dg-error "too small" } + ierr = lstat (name, values= buff13) + ierr = fstat (unit, values= buff12) ! { dg-error "too small" } + ierr = fstat (unit, values= buff13) + ierr = stat (name, values=(buff13)) ! { dg-error "must be a variable" } + ierr = lstat (name, values=(buff13)) ! { dg-error "must be a variable" } + ierr = fstat (unit, values=(buff13)) ! { dg-error "must be a variable" } +end + +subroutine sub2 () + integer, parameter :: ik = kind(1) + integer(ik) :: buff12(12) + integer(ik), target :: buff13(13) = 0 + integer(ik) :: unit = 10 + integer(ik), target :: ierr = 0 + character(len=64) :: name = "/etc/passwd" + integer(ik),pointer :: pbuf(:) => buff13 + integer(ik),pointer :: perr => ierr + call stat (name, status=ierr, values= buff12) ! { dg-error "too small" } + call stat (name, status=ierr, values= buff13) + call lstat (name, status=ierr, values= buff12) ! { dg-error "too small" } + call lstat (name, status=ierr, values= buff13) + call fstat (unit, status=ierr, values= buff12) ! { dg-error "too small" } + call fstat (unit, status=ierr, values= buff13) + call stat (name, status=ierr, values=(buff13)) ! { dg-error "must be a variable" } + call lstat (name, status=ierr, values=(buff13)) ! { dg-error "must be a variable" } + call fstat (unit, status=ierr, values=(buff13)) ! { dg-error "must be a variable" } + call stat (name, status=(ierr),values=buff13) ! { dg-error "must be a variable" } + call lstat (name, status=(ierr),values=buff13) ! { dg-error "must be a variable" } + call fstat (unit, status=(ierr),values=buff13) ! { dg-error "must be a variable" } + call stat (name, status=perr, values= pbuf) + call lstat (name, status=perr, values= pbuf) + call fstat (unit, status=perr, values= pbuf) +end diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 1c5427e..72763fd 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -8339,7 +8339,7 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags) fprintf (file, ", "); tree name = get_attribute_name (chain); - print_generic_expr (file, name, dump_flags); + print_generic_expr (file, name, flags); if (TREE_VALUE (chain) != NULL_TREE) { fprintf (file, " ("); @@ -8350,13 +8350,13 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags) "omp declare variant base")) { tree a = TREE_VALUE (chain); - print_generic_expr (file, TREE_PURPOSE (a), dump_flags); + print_generic_expr (file, TREE_PURPOSE (a), flags); fprintf (file, " match "); print_omp_context_selector (file, TREE_VALUE (a), - dump_flags); + flags); } else - print_generic_expr (file, TREE_VALUE (chain), dump_flags); + print_generic_expr (file, TREE_VALUE (chain), flags); fprintf (file, ")"); } } @@ -8378,7 +8378,7 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags) } print_generic_expr (file, TREE_TYPE (TREE_TYPE (fndecl)), - dump_flags | TDF_SLIM); + flags | TDF_SLIM); fprintf (file, " __GIMPLE (%s", (fun->curr_properties & PROP_ssa) ? "ssa" : (fun->curr_properties & PROP_cfg) ? "cfg" @@ -8391,7 +8391,7 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags) fprintf (file, ",%s(%" PRIu64 ")", profile_quality_as_string (bb->count.quality ()), bb->count.value ()); - if (dump_flags & TDF_UID) + if (flags & TDF_UID) fprintf (file, ")\n%sD_%u (", function_name (fun), DECL_UID (fndecl)); else @@ -8400,8 +8400,8 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags) } else { - print_generic_expr (file, TREE_TYPE (fntype), dump_flags); - if (dump_flags & TDF_UID) + print_generic_expr (file, TREE_TYPE (fntype), flags); + if (flags & TDF_UID) fprintf (file, " %sD.%u %s(", function_name (fun), DECL_UID (fndecl), tmclone ? "[tm-clone] " : ""); else @@ -8412,9 +8412,9 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags) arg = DECL_ARGUMENTS (fndecl); while (arg) { - print_generic_expr (file, TREE_TYPE (arg), dump_flags); + print_generic_expr (file, TREE_TYPE (arg), flags); fprintf (file, " "); - print_generic_expr (file, arg, dump_flags); + print_generic_expr (file, arg, flags); if (DECL_CHAIN (arg)) fprintf (file, ", "); arg = DECL_CHAIN (arg); diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 5e97fdb..0f0770a 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -1628,10 +1628,8 @@ irange::contains_p (const wide_int &cst) const if (undefined_p ()) return false; - // See if we can exclude CST based on the known 0 bits. - if (!m_bitmask.unknown_p () - && cst != 0 - && wi::bit_and (m_bitmask.get_nonzero_bits (), cst) == 0) + // Check is the known bits in bitmask exclude CST. + if (!m_bitmask.member_p (cst)) return false; signop sign = TYPE_SIGN (type ()); @@ -1899,12 +1897,17 @@ irange::irange_contains_p (const irange &r) const gcc_checking_assert (!undefined_p () && !varying_p ()); gcc_checking_assert (!r.undefined_p () && !varying_p ()); + // Check singletons directly which will include any bitmasks. + wide_int rl; + if (r.singleton_p (rl)) + return contains_p (rl); + // In order for THIS to fully contain R, all of the pairs within R must // be fully contained by the pairs in this object. signop sign = TYPE_SIGN (m_type); unsigned ri = 0; unsigned i = 0; - wide_int rl = r.m_base[0]; + rl = r.m_base[0]; wide_int ru = r.m_base[1]; wide_int l = m_base[0]; wide_int u = m_base[1]; @@ -1973,6 +1976,16 @@ irange::intersect (const vrange &v) return res; } + // If either range is a singleton and the other range does not contain + // it, the result is undefined. + wide_int val; + if ((singleton_p (val) && !r.contains_p (val)) + || (r.singleton_p (val) && !contains_p (val))) + { + set_undefined (); + return true; + } + // If R fully contains this, then intersection will change nothing. if (r.irange_contains_p (*this)) return intersect_bitmask (r); @@ -2535,15 +2548,14 @@ irange::intersect_bitmask (const irange &r) irange_bitmask bm = get_bitmask (); irange_bitmask save = bm; bm.intersect (r.get_bitmask ()); - if (save == bm) - return false; - + // Use ths opportunity to make sure mask reflects always reflects the + // best mask we have. m_bitmask = bm; // Updating m_bitmask may still yield a semantic bitmask (as // returned by get_bitmask) which is functionally equivalent to what // we originally had. In which case, there's still no change. - if (save == get_bitmask ()) + if (save == bm || save == get_bitmask ()) return false; if (!set_range_from_bitmask ()) diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc index 4c78759..ff11656 100644 --- a/gcc/vr-values.cc +++ b/gcc/vr-values.cc @@ -513,85 +513,6 @@ simplify_using_ranges::legacy_fold_cond (gcond *stmt, edge *taken_edge_p) } } -/* Searches the case label vector VEC for the ranges of CASE_LABELs that are - used in range VR. The indices are placed in MIN_IDX1, MAX_IDX, MIN_IDX2 and - MAX_IDX2. If the ranges of CASE_LABELs are empty then MAX_IDX1 < MIN_IDX1. - Returns true if the default label is not needed. */ - -static bool -find_case_label_ranges (gswitch *stmt, const irange *vr, - size_t *min_idx1, size_t *max_idx1, - size_t *min_idx2, size_t *max_idx2) -{ - size_t i, j, k, l; - unsigned int n = gimple_switch_num_labels (stmt); - bool take_default; - tree case_low, case_high; - tree min, max; - value_range_kind kind = get_legacy_range (*vr, min, max); - - gcc_checking_assert (!vr->varying_p () && !vr->undefined_p ()); - - take_default = !find_case_label_range (stmt, min, max, &i, &j); - - /* Set second range to empty. */ - *min_idx2 = 1; - *max_idx2 = 0; - - if (kind == VR_RANGE) - { - *min_idx1 = i; - *max_idx1 = j; - return !take_default; - } - - /* Set first range to all case labels. */ - *min_idx1 = 1; - *max_idx1 = n - 1; - - if (i > j) - return false; - - /* Make sure all the values of case labels [i , j] are contained in - range [MIN, MAX]. */ - case_low = CASE_LOW (gimple_switch_label (stmt, i)); - case_high = CASE_HIGH (gimple_switch_label (stmt, j)); - if (tree_int_cst_compare (case_low, min) < 0) - i += 1; - if (case_high != NULL_TREE - && tree_int_cst_compare (max, case_high) < 0) - j -= 1; - - if (i > j) - return false; - - /* If the range spans case labels [i, j], the corresponding anti-range spans - the labels [1, i - 1] and [j + 1, n - 1]. */ - k = j + 1; - l = n - 1; - if (k > l) - { - k = 1; - l = 0; - } - - j = i - 1; - i = 1; - if (i > j) - { - i = k; - j = l; - k = 1; - l = 0; - } - - *min_idx1 = i; - *max_idx1 = j; - *min_idx2 = k; - *max_idx2 = l; - return false; -} - /* Simplify boolean operations if the source is known to be already a boolean. */ bool @@ -1023,6 +944,10 @@ range_fits_type_p (const irange *vr, widest_int tem; signop src_sgn; + /* Now we can only handle ranges with constant bounds. */ + if (vr->undefined_p () || vr->varying_p ()) + return false; + /* We can only handle integral and pointer types. */ src_type = vr->type (); if (!INTEGRAL_TYPE_P (src_type) @@ -1031,17 +956,13 @@ range_fits_type_p (const irange *vr, /* An extension is fine unless VR is SIGNED and dest_sgn is UNSIGNED, and so is an identity transform. */ - src_precision = TYPE_PRECISION (vr->type ()); + src_precision = TYPE_PRECISION (src_type); src_sgn = TYPE_SIGN (src_type); if ((src_precision < dest_precision && !(dest_sgn == UNSIGNED && src_sgn == SIGNED)) || (src_precision == dest_precision && src_sgn == dest_sgn)) return true; - /* Now we can only handle ranges with constant bounds. */ - if (vr->undefined_p () || vr->varying_p ()) - return false; - wide_int vrmin = vr->lower_bound (); wide_int vrmax = vr->upper_bound (); @@ -1374,157 +1295,99 @@ bool simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt) { tree op = gimple_switch_index (stmt); - int_range_max vr; - bool take_default; + tree type = TREE_TYPE (op); + int_range_max op_range (type); + int_range_max default_range (type); + auto_vec<unsigned> cases; + cases.truncate (0); edge e; - edge_iterator ei; - size_t i = 0, j = 0, n, n2; - tree vec2; switch_update su; - size_t k = 1, l = 0; - - if (TREE_CODE (op) == SSA_NAME) - { - if (!query->range_of_expr (vr, op, stmt) - || vr.varying_p () || vr.undefined_p ()) - return false; - /* Find case label for min/max of the value range. */ - take_default = !find_case_label_ranges (stmt, &vr, &i, &j, &k, &l); - } - else if (TREE_CODE (op) == INTEGER_CST) - { - take_default = !find_case_label_index (stmt, 1, op, &i); - if (take_default) - { - i = 1; - j = 0; - } - else - { - j = i; - } - } - else + // Abort if we don't have a useful range for the switch index. + if (!query->range_of_expr (op_range, op, stmt) + || op_range.varying_p () || op_range.undefined_p ()) return false; - n = gimple_switch_num_labels (stmt); + // Default range starts with full known range of op. + default_range = op_range; + edge default_edge = gimple_switch_default_edge (cfun, stmt); - /* We can truncate the case label ranges that partially overlap with OP's - value range. */ - size_t min_idx = 1, max_idx = 0; - tree min, max; - value_range_kind kind = get_legacy_range (vr, min, max); - if (!vr.undefined_p ()) - find_case_label_range (stmt, min, max, &min_idx, &max_idx); - if (min_idx <= max_idx) + unsigned x, lim = gimple_switch_num_labels (stmt); + for (x = 1; x < lim; x++) { - tree min_label = gimple_switch_label (stmt, min_idx); - tree max_label = gimple_switch_label (stmt, max_idx); + e = gimple_switch_edge (cfun, stmt, x); + tree label = gimple_switch_label (stmt, x); + + // If this edge is the same as the default edge, do nothing else. + if (e == default_edge) + continue; + // Ada sometimes has mismatched labels and index. Just bail. + if (TREE_TYPE (CASE_LOW (label)) != type) + return false; - /* Avoid changing the type of the case labels when truncating. */ - tree case_label_type = TREE_TYPE (CASE_LOW (min_label)); - tree vr_min = fold_convert (case_label_type, min); - tree vr_max = fold_convert (case_label_type, max); + wide_int low = wi::to_wide (CASE_LOW (label)); + wide_int high; + // Singleton cases have no CASE_HIGH. + tree tree_high = CASE_HIGH (label); + if (tree_high) + high = wi::to_wide (tree_high); + else + high = low; - if (kind == VR_RANGE) + // If the case range is fully contained in op_range, leave the + // case as it is, otherwise adjust the labels. + int_range_max case_range (type, low, high); + if (case_range.intersect (op_range)) { - /* If OP's value range is [2,8] and the low label range is - 0 ... 3, truncate the label's range to 2 .. 3. */ - if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0 - && CASE_HIGH (min_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0) - CASE_LOW (min_label) = vr_min; - - /* If OP's value range is [2,8] and the high label range is - 7 ... 10, truncate the label's range to 7 .. 8. */ - if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0 - && CASE_HIGH (max_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0) - CASE_HIGH (max_label) = vr_max; - } - else if (kind == VR_ANTI_RANGE) - { - tree one_cst = build_one_cst (case_label_type); - - if (min_label == max_label) - { - /* If OP's value range is ~[7,8] and the label's range is - 7 ... 10, truncate the label's range to 9 ... 10. */ - if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) == 0 - && CASE_HIGH (min_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) > 0) - CASE_LOW (min_label) - = int_const_binop (PLUS_EXPR, vr_max, one_cst); - - /* If OP's value range is ~[7,8] and the label's range is - 5 ... 8, truncate the label's range to 5 ... 6. */ - if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0 - && CASE_HIGH (min_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) == 0) - CASE_HIGH (min_label) - = int_const_binop (MINUS_EXPR, vr_min, one_cst); - } + // If none of the label is in op_range, skip this label. + if (case_range.undefined_p ()) + continue; + + // Part of the label is in op_range, but not all of it. CASE_RANGE + // contains the part that is. Adjust the case range to + // the new min/max. + if (case_range.lower_bound () != low) + CASE_LOW (label) = wide_int_to_tree (type, + case_range.lower_bound ()); + if (case_range.singleton_p ()) + CASE_HIGH (label) = NULL_TREE; else - { - /* If OP's value range is ~[2,8] and the low label range is - 0 ... 3, truncate the label's range to 0 ... 1. */ - if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0 - && CASE_HIGH (min_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0) - CASE_HIGH (min_label) - = int_const_binop (MINUS_EXPR, vr_min, one_cst); - - /* If OP's value range is ~[2,8] and the high label range is - 7 ... 10, truncate the label's range to 9 ... 10. */ - if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0 - && CASE_HIGH (max_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0) - CASE_LOW (max_label) - = int_const_binop (PLUS_EXPR, vr_max, one_cst); - } + if (case_range.upper_bound () != high) + CASE_HIGH (label) = wide_int_to_tree (type, + case_range.upper_bound ()); } - - /* Canonicalize singleton case ranges. */ - if (tree_int_cst_equal (CASE_LOW (min_label), CASE_HIGH (min_label))) - CASE_HIGH (min_label) = NULL_TREE; - if (tree_int_cst_equal (CASE_LOW (max_label), CASE_HIGH (max_label))) - CASE_HIGH (max_label) = NULL_TREE; + // Add case label to the keep list. + cases.safe_push (x); + // Remove case_range from needing to be handled by the default. + case_range.invert (); + default_range.intersect (case_range); } - /* We can also eliminate case labels that lie completely outside OP's value - range. */ - - /* Bail out if this is just all edges taken. */ - if (i == 1 - && j == n - 1 - && take_default) + // An undefined DEFAULT range means the current default case is not needed. + unsigned idx = default_range.undefined_p () ? 0 : 1; + unsigned vec_size = cases.length () + idx; + if (vec_size == lim) return false; - /* Build a new vector of taken case labels. */ - vec2 = make_tree_vec (j - i + 1 + l - k + 1 + (int)take_default); - n2 = 0; - - /* Add the default edge, if necessary. */ - if (take_default) - TREE_VEC_ELT (vec2, n2++) = gimple_switch_default_label (stmt); - - for (; i <= j; ++i, ++n2) - TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, i); - - for (; k <= l; ++k, ++n2) - TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, k); + tree vec2 = make_tree_vec (vec_size); + // Add default label if there is one. + if (idx) + { + TREE_VEC_ELT (vec2, 0) = gimple_switch_default_label (stmt); + e = gimple_switch_edge (cfun, stmt, 0); + e->aux = (void *)-1; + } - /* Mark needed edges. */ - for (i = 0; i < n2; ++i) + for (x = 0; x < cases.length (); x++) { - e = find_edge (gimple_bb (stmt), - label_to_block (cfun, - CASE_LABEL (TREE_VEC_ELT (vec2, i)))); - e->aux = (void *)-1; + unsigned swi = cases[x]; + TREE_VEC_ELT (vec2, idx++) = gimple_switch_label (stmt, swi); + e = gimple_switch_edge (cfun, stmt, swi); + e->aux = (void *)-1; } /* Queue not needed edges for later removal. */ + edge_iterator ei; FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs) { if (e->aux == (void *)-1) |