diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 42 | ||||
-rw-r--r-- | gcc/DATESTAMP | 2 | ||||
-rw-r--r-- | gcc/cfgexpand.cc | 49 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-sve.md | 37 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 35 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/cp/coroutines.cc | 57 | ||||
-rw-r--r-- | gcc/cp/coroutines.h | 4 | ||||
-rw-r--r-- | gcc/gcc.cc | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 37 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/coroutines/coro-missing-final-suspend.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/coroutines/coro1-missing-await-method.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/coroutines/pr104051-0.C (renamed from gcc/testsuite/g++.dg/coroutines/pr104051.C) | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/coroutines/pr104051-1.C | 23 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/coroutines/pr116775.C | 68 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr119160.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/avr/torture/pr120423-1.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/avr/torture/pr120423-116389.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/avr/torture/pr120423-2.c | 30 |
20 files changed, 475 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 549505e..0eaaf7c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,45 @@ +2025-06-14 Georg-Johann Lay <avr@gjlay.de> + + Backported from master: + 2025-06-14 Georg-Johann Lay <avr@gjlay.de> + + PR rtl-optimization/120423 + PR rtl-optimization/116389 + * config/avr/avr.md [-mno-lra]: Add pre-reload split to transform + (left shift of) a paradoxical subreg to a (left shift of) zero-extend. + +2025-06-13 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/120629 + * cfgexpand.cc (expand_split_edge): New function. + (expand_gimple_cond, construct_init_block): Use it. + +2025-06-13 Spencer Abson <spencer.abson@arm.com> + + PR target/118150 + * config/aarch64/aarch64-sve.md (*one_cmpl<mode>3_cc): New + combiner pattern. + (*one_cmpl<mode>3_ptest): Likewise. + +2025-06-13 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/120629 + * cfgexpand.cc (construct_init_block): If first_block isn't BB_RTL, + has any PHI nodes and false_edge->dest_idx before redirection is + different from make_single_succ_edge result's dest_idx, swap the + latter with the former last pred edge and their dest_idx members. + +2025-06-13 Kito Cheng <kito.cheng@sifive.com> + + * gcc.cc (driver::set_up_specs): Use gcc_exec_prefix to + read the spec file rather than standard_exec_prefix. + +2025-06-13 H.J. Lu <hjl.tools@gmail.com> + + PR target/120589 + * config/mcore/mcore.cc (mcore_mark_dllimport): Don't use + gen_rtx_MEM. + 2025-06-12 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/120638 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index c544224..caed742 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20250613 +20250615 diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc index f288a54..e1cdb71 100644 --- a/gcc/cfgexpand.cc +++ b/gcc/cfgexpand.cc @@ -2830,6 +2830,31 @@ expand_remove_edge (edge e) remove_edge (e); } +/* Split edge E during expansion and instead of creating a new + bb on that edge, add there BB. FLAGS should be flags on the + new edge from BB to former E->dest. */ + +static void +expand_split_edge (edge e, basic_block bb, int flags) +{ + unsigned int dest_idx = e->dest_idx; + basic_block dest = e->dest; + redirect_edge_succ (e, bb); + e = make_single_succ_edge (bb, dest, flags); + if ((dest->flags & BB_RTL) == 0 + && phi_nodes (dest) + && e->dest_idx != dest_idx) + { + /* If there are any PHI nodes on dest, swap the new succ edge + with the one moved into false_edge's former position, so that + PHI arguments don't need adjustment. */ + edge e2 = EDGE_PRED (dest, dest_idx); + std::swap (e->dest_idx, e2->dest_idx); + std::swap (EDGE_PRED (dest, e->dest_idx), + EDGE_PRED (dest, e2->dest_idx)); + } +} + /* A subroutine of expand_gimple_cond. Given E, a fallthrough edge of a basic block where we just expanded the conditional at the end, @@ -3013,8 +3038,7 @@ expand_gimple_cond (basic_block bb, gcond *stmt) new_bb = create_basic_block (NEXT_INSN (last), get_last_insn (), bb); dest = false_edge->dest; - unsigned int dest_idx = false_edge->dest_idx; - redirect_edge_succ (false_edge, new_bb); + expand_split_edge (false_edge, new_bb, 0); false_edge->flags |= EDGE_FALLTHRU; new_bb->count = false_edge->count (); loop_p loop = find_common_loop (bb->loop_father, dest->loop_father); @@ -3022,19 +3046,6 @@ expand_gimple_cond (basic_block bb, gcond *stmt) if (loop->latch == bb && loop->header == dest) loop->latch = new_bb; - edge e = make_single_succ_edge (new_bb, dest, 0); - if ((dest->flags & BB_RTL) == 0 - && phi_nodes (dest) - && e->dest_idx != dest_idx) - { - /* If there are any PHI nodes on dest, swap the new succ edge - with the one moved into false_edge's former position, so that - PHI arguments don't need adjustment. */ - edge e2 = EDGE_PRED (dest, dest_idx); - std::swap (e->dest_idx, e2->dest_idx); - std::swap (EDGE_PRED (dest, e->dest_idx), - EDGE_PRED (dest, e2->dest_idx)); - } if (BARRIER_P (BB_END (new_bb))) BB_END (new_bb) = PREV_INSN (BB_END (new_bb)); update_bb_for_insn (new_bb); @@ -6538,7 +6549,7 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) static basic_block construct_init_block (void) { - basic_block init_block, first_block; + basic_block init_block; edge e = NULL; int flags; @@ -6569,11 +6580,7 @@ construct_init_block (void) init_block->count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count; add_bb_to_loop (init_block, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father); if (e) - { - first_block = e->dest; - redirect_edge_succ (e, init_block); - make_single_succ_edge (init_block, first_block, flags); - } + expand_split_edge (e, init_block, flags); else make_single_succ_edge (init_block, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FALLTHRU); diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index c5d3e8c..7cb13e7 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -3948,6 +3948,7 @@ ;; ------------------------------------------------------------------------- ;; Includes: ;; - NOT +;; - NOTS ;; ------------------------------------------------------------------------- ;; Unpredicated predicate inverse. @@ -3972,6 +3973,42 @@ "not\t%0.b, %1/z, %2.b" ) +;; Predicated predicate inverse in which the flags are set in the same +;; way as a PTEST. +(define_insn "*one_cmpl<mode>3_cc" + [(set (reg:CC_NZC CC_REGNUM) + (unspec:CC_NZC + [(match_operand:VNx16BI 1 "register_operand" "Upa") + (match_operand 3) + (match_operand:SI 4 "aarch64_sve_ptrue_flag") + (and:PRED_ALL + (not:PRED_ALL + (match_operand:PRED_ALL 2 "register_operand" "Upa")) + (match_dup 3))] + UNSPEC_PTEST)) + (set (match_operand:PRED_ALL 0 "register_operand" "=Upa") + (and:PRED_ALL (not:PRED_ALL (match_dup 2)) (match_dup 3)))] + "TARGET_SVE" + "nots\t%0.b, %1/z, %2.b" +) + +;; Same, where only the flags result is interesting. +(define_insn "*one_cmpl<mode>3_ptest" + [(set (reg:CC_NZC CC_REGNUM) + (unspec:CC_NZC + [(match_operand:VNx16BI 1 "register_operand" "Upa") + (match_operand 3) + (match_operand:SI 4 "aarch64_sve_ptrue_flag") + (and:PRED_ALL + (not:PRED_ALL + (match_operand:PRED_ALL 2 "register_operand" "Upa")) + (match_dup 3))] + UNSPEC_PTEST)) + (clobber (match_scratch:PRED_ALL 0 "=Upa"))] + "TARGET_SVE" + "nots\t%0.b, %1/z, %2.b" +) + ;; ========================================================================= ;; == Binary arithmetic ;; ========================================================================= diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 01b8e4b..f8bbdc7 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -5273,6 +5273,41 @@ ;;<< << << << << << << << << << << << << << << << << << << << << << << << << << ;; arithmetic shift left +;; Work around PR120423: Transform left shift of a paradoxical subreg +;; into left shift of the zero-extended entity. +(define_split ; PR120423 + [(set (match_operand:HISI 0 "register_operand") + (ashift:HISI (subreg:HISI (match_operand:QIPSI 1 "nonimmediate_operand") + 0) + (match_operand:QI 2 "const_int_operand")))] + "!reload_completed + && !avropt_lra_p + && <HISI:SIZE> > <QIPSI:SIZE>" + [(set (match_dup 4) + (zero_extend:HISI (match_dup 5))) + (set (match_dup 0) + (ashift:HISI (match_dup 4) + (match_dup 2)))] + { + operands[4] = gen_reg_rtx (<HISI:MODE>mode); + operands[5] = force_reg (<QIPSI:MODE>mode, operands[1]); + }) + +;; Similar happens for PR116389. +(define_split ; PR116389 + [(set (match_operand:HISI 0 "register_operand") + (subreg:HISI (match_operand:QIPSI 1 "nonimmediate_operand") + 0))] + "!reload_completed + && !avropt_lra_p + && <HISI:SIZE> > <QIPSI:SIZE>" + [(set (match_dup 0) + (zero_extend:HISI (match_dup 2)))] + { + operands[2] = force_reg (<QIPSI:MODE>mode, operands[1]); + }) + + ;; "ashlqi3" ;; "ashlqq3" "ashluqq3" (define_expand "ashl<mode>3" diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 842f74d..41d68ed 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,27 @@ +2025-06-14 Iain Sandoe <iain@sandoe.co.uk> + + * coroutines.cc (build_co_await): Identify diagnostics + for initial and final await expressions. + (cp_coroutine_transform::wrap_original_function_body): Do + not handle initial and final await expressions here ... + (cp_coroutine_transform::apply_transforms): ... handle them + here and avoid duplicate diagnostics. + * coroutines.h: Declare inital and final await expressions + in the transform class. Save the function closing brace + location. + +2025-06-13 Iain Sandoe <iain@sandoe.co.uk> + + PR c++/116775 + * coroutines.cc (analyze_expression_awaits): When we see + a builtin_constant_p call, and that contains one or more + await expressions, then replace the call with its result + and discard the unevaluated operand. + +2025-06-13 Iain Sandoe <iain@sandoe.co.uk> + + * coroutines.cc (build_actor_fn): Set can_throw. + 2025-06-12 Alfie Richards <alfie.richards@arm.com> * decl.cc (maybe_version_functions): Change record_function_versions diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 97eee6e..4057a07 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -1277,8 +1277,14 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind, if (TREE_CODE (o_type) != RECORD_TYPE) { - error_at (loc, "awaitable type %qT is not a structure", - o_type); + if (suspend_kind == FINAL_SUSPEND_POINT) + error_at (loc, "%qs awaitable type %qT is not a structure", + "final_suspend()", o_type); + else if (suspend_kind == INITIAL_SUSPEND_POINT) + error_at (loc, "%qs awaitable type %qT is not a structure", + "initial_suspend()", o_type); + else + error_at (loc, "awaitable type %qT is not a structure", o_type); return error_mark_node; } @@ -2406,6 +2412,11 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, bool spf = start_preparsed_function (actor, NULL_TREE, SF_PRE_PARSED); gcc_checking_assert (spf); gcc_checking_assert (cfun && current_function_decl && TREE_STATIC (actor)); + if (flag_exceptions) + /* We, unconditionally, add a try/catch and rethrow. + TODO: Determine if the combination of initial suspend and the original + body cannot throw, and elide these additions. */ + cp_function_chain->can_throw = true; tree stmt = begin_function_body (); tree actor_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL); @@ -3420,7 +3431,8 @@ maybe_promote_temps (tree *stmt, void *d) return cp_walk_tree (stmt, register_awaits, d, &visited); } -/* Lightweight callback to determine two key factors: +/* Relatively lightweight callback to do initial assessment: + 0) Rewrite some await expressions. 1) If the statement/expression contains any await expressions. 2) If the statement/expression potentially requires a re-write to handle TRUTH_{AND,OR}IF_EXPRs since, in most cases, they will need expansion @@ -3437,6 +3449,26 @@ analyze_expression_awaits (tree *stmt, int *do_subtree, void *d) switch (TREE_CODE (*stmt)) { default: return NULL_TREE; + case CALL_EXPR: + { + tree fn = cp_get_callee_fndecl_nofold (*stmt); + /* Special-cases where we want to re-write await expressions to some + other value before they are otherwise processed. */ + if (fn && DECL_IS_BUILTIN_CONSTANT_P (fn)) + { + gcc_checking_assert (call_expr_nargs (*stmt) == 1); + tree expr = CALL_EXPR_ARG (*stmt, 0); + if (cp_walk_tree (&expr, find_any_await, nullptr, NULL)) + { + if (TREE_CONSTANT (maybe_constant_value (expr))) + *stmt = integer_one_node; + else + *stmt = integer_zero_node; + } + *do_subtree = 0; + } + } + break; case CO_YIELD_EXPR: /* co_yield is syntactic sugar, re-write it to co_await. */ *stmt = TREE_OPERAND (*stmt, 1); @@ -4330,7 +4362,6 @@ cp_coroutine_transform::wrap_original_function_body () /* Wrap the function body in a try {} catch (...) {} block, if exceptions are enabled. */ tree var_list = NULL_TREE; - tree initial_await = build_init_or_final_await (fn_start, false); /* [stmt.return.coroutine] / 3 If p.return_void() is a valid expression, flowing off the end of a @@ -4524,7 +4555,8 @@ cp_coroutine_transform::wrap_original_function_body () zero_resume = build2_loc (loc, MODIFY_EXPR, act_des_fn_ptr_type, resume_fn_ptr, zero_resume); finish_expr_stmt (zero_resume); - finish_expr_stmt (build_init_or_final_await (fn_start, true)); + finish_expr_stmt (final_await); + BIND_EXPR_BODY (update_body) = pop_stmt_list (BIND_EXPR_BODY (update_body)); BIND_EXPR_VARS (update_body) = nreverse (var_list); BLOCK_VARS (top_block) = BIND_EXPR_VARS (update_body); @@ -5181,9 +5213,10 @@ cp_coroutine_transform::cp_coroutine_transform (tree _orig_fn, bool _inl) } /* We don't have the locus of the opening brace - it's filled in later (and - there doesn't really seem to be any easy way to get at it). - The closing brace is assumed to be input_location. */ + there doesn't really seem to be any easy way to get at it). */ fn_start = DECL_SOURCE_LOCATION (orig_fn_decl); + /* The closing brace is assumed to be input_location. */ + fn_end = input_location; /* Build types we need. */ tree fr_name = get_fn_local_identifier (orig_fn_decl, "Frame"); @@ -5262,6 +5295,16 @@ cp_coroutine_transform::apply_transforms () = coro_build_actor_or_destroy_function (orig_fn_decl, act_des_fn_type, frame_ptr_type, false); + /* Avoid repeating diagnostics about promise or awaiter fails. */ + if (!seen_error ()) + { + iloc_sentinel stable_input_loc (fn_start); + initial_await = build_init_or_final_await (fn_start, false); + input_location = fn_end; + if (initial_await && initial_await != error_mark_node) + final_await = build_init_or_final_await (fn_end, true); + } + /* Transform the function body as per [dcl.fct.def.coroutine] / 5. */ wrap_original_function_body (); diff --git a/gcc/cp/coroutines.h b/gcc/cp/coroutines.h index 55caa6e..919dc9a 100644 --- a/gcc/cp/coroutines.h +++ b/gcc/cp/coroutines.h @@ -102,6 +102,7 @@ private: tree orig_fn_decl; /* The original function decl. */ tree orig_fn_body = NULL_TREE; /* The original function body. */ location_t fn_start = UNKNOWN_LOCATION; + location_t fn_end = UNKNOWN_LOCATION; tree resumer = error_mark_node; tree destroyer = error_mark_node; tree coroutine_body = NULL_TREE; @@ -126,6 +127,9 @@ private: bool inline_p = false; bool valid_coroutine = false; + tree initial_await = error_mark_node; + tree final_await = error_mark_node; + void analyze_fn_parms (); void wrap_original_function_body (); bool build_ramp_function (); @@ -8506,11 +8506,13 @@ driver::set_up_specs () const spec_machine_suffix = just_machine_suffix; #endif + const char *exec_prefix + = gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix; /* We need to check standard_exec_prefix/spec_machine_suffix/specs for any override of as, ld and libraries. */ - specs_file = (char *) alloca (strlen (standard_exec_prefix) - + strlen (spec_machine_suffix) + sizeof ("specs")); - strcpy (specs_file, standard_exec_prefix); + specs_file = (char *) alloca ( + strlen (exec_prefix) + strlen (spec_machine_suffix) + sizeof ("specs")); + strcpy (specs_file, exec_prefix); strcat (specs_file, spec_machine_suffix); strcat (specs_file, "specs"); if (access (specs_file, R_OK) == 0) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 80cc664..c339beb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,40 @@ +2025-06-14 Georg-Johann Lay <avr@gjlay.de> + + Backported from master: + 2025-06-14 Georg-Johann Lay <avr@gjlay.de> + + PR rtl-optimization/120423 + PR rtl-optimization/116389 + * gcc.target/avr/torture/pr120423-1.c: New test. + * gcc.target/avr/torture/pr120423-2.c: New test. + * gcc.target/avr/torture/pr120423-116389.c: New test. + +2025-06-14 Iain Sandoe <iain@sandoe.co.uk> + + * g++.dg/coroutines/coro1-missing-await-method.C: Adjust for + improved diagnostics. + * g++.dg/coroutines/coro-missing-final-suspend.C: Likewise. + * g++.dg/coroutines/pr104051.C: Move to... + * g++.dg/coroutines/pr104051-0.C: ...here. + * g++.dg/coroutines/pr104051-1.C: New test. + +2025-06-13 Iain Sandoe <iain@sandoe.co.uk> + + PR c++/116775 + * g++.dg/coroutines/pr116775.C: New test. + +2025-06-13 Spencer Abson <spencer.abson@arm.com> + + PR target/118150 + * gcc.target/aarch64/sve/acle/general/not_1.c: New test. + +2025-06-13 Konstantinos Eleftheriou <konstantinos.eleftheriou@vrull.eu> + + PR testsuite/119862 + * gcc.dg/pr119160.c: Added empty definitions for + `__cyg_profile_func_enter` and `__cyg_profile_func_exit` + functions. + 2025-06-12 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/120638 diff --git a/gcc/testsuite/g++.dg/coroutines/coro-missing-final-suspend.C b/gcc/testsuite/g++.dg/coroutines/coro-missing-final-suspend.C index 6a0878c..b252231 100644 --- a/gcc/testsuite/g++.dg/coroutines/coro-missing-final-suspend.C +++ b/gcc/testsuite/g++.dg/coroutines/coro-missing-final-suspend.C @@ -7,10 +7,10 @@ #include "coro1-ret-int-yield-int.h" coro1 -my_coro () // { dg-error {no member named 'final_suspend' in} } +my_coro () { co_return 0; -} +} // { dg-error {no member named 'final_suspend' in} } // check we have not messed up continuation of the compilation. template <class... Args> diff --git a/gcc/testsuite/g++.dg/coroutines/coro1-missing-await-method.C b/gcc/testsuite/g++.dg/coroutines/coro1-missing-await-method.C index c1869e0..c6a3188 100644 --- a/gcc/testsuite/g++.dg/coroutines/coro1-missing-await-method.C +++ b/gcc/testsuite/g++.dg/coroutines/coro1-missing-await-method.C @@ -7,7 +7,7 @@ #include "coro1-ret-int-yield-int.h" coro1 -bar0 () // { dg-error {no member named 'await_suspend' in 'coro1::suspend_always_prt'} } +bar0 () { co_await coro1::suspend_never_prt{}; // { dg-error {no member named 'await_ready' in 'coro1::suspend_never_prt'} } co_yield 5; // { dg-error {no member named 'await_suspend' in 'coro1::suspend_always_prt'} } diff --git a/gcc/testsuite/g++.dg/coroutines/pr104051.C b/gcc/testsuite/g++.dg/coroutines/pr104051-0.C index f77a915..bf878b2 100644 --- a/gcc/testsuite/g++.dg/coroutines/pr104051.C +++ b/gcc/testsuite/g++.dg/coroutines/pr104051-0.C @@ -24,7 +24,7 @@ template <typename T> struct task { std::coroutine_handle<> await_suspend(std::coroutine_handle<>); T await_resume(); }; -task<std::vector<int>> foo() { // { dg-error {awaitable type 'bool' is not a structure} } +task<std::vector<int>> foo() { while ((co_await foo()).empty()) ; -} +} // { dg-error {'final_suspend\(\)' awaitable type 'bool' is not a structure} } diff --git a/gcc/testsuite/g++.dg/coroutines/pr104051-1.C b/gcc/testsuite/g++.dg/coroutines/pr104051-1.C new file mode 100644 index 0000000..35b5e2c --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr104051-1.C @@ -0,0 +1,23 @@ +// { dg-additional-options "-fsyntax-only" } +// { dg-skip-if "requires hosted libstdc++ for vector" { ! hostedlib } } +#include <coroutine> +template <typename> +struct promise { + auto get_return_object() { + return std::coroutine_handle<promise>::from_promise(*this); + } + auto initial_suspend() { return 42.0; } + auto final_suspend() noexcept { return true; } + void unhandled_exception(); + void return_void (); +}; +template <typename T> struct task { + using promise_type = promise<T>; + task(std::coroutine_handle<promise<T>>); + bool await_ready(); + std::coroutine_handle<> await_suspend(std::coroutine_handle<>); + T await_resume(); +}; +task<double> foo() { // { dg-error {'initial_suspend\(\)' awaitable type 'double' is not a structure} } + co_return; +} diff --git a/gcc/testsuite/g++.dg/coroutines/pr116775.C b/gcc/testsuite/g++.dg/coroutines/pr116775.C new file mode 100644 index 0000000..981e27a --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr116775.C @@ -0,0 +1,68 @@ +// { dg-additional-options "-fsyntax-only" } +// PR116775 +#include <coroutine> +#ifndef OUTPUT +# define PRINT(X) +# define PRINTF(...) +#else +#include <cstdio> +# define PRINT(X) puts(X) +# define PRINTF(...) printf(__VA_ARGS__) +#endif + +struct awaitable { + awaitable(int n) : delay{n} {} + + constexpr bool await_ready() const noexcept { return false; } + auto await_suspend(std::coroutine_handle<> h) const { + __builtin_trap (); + return false; + } + int await_resume() const noexcept { + return delay; + } + + int delay; +}; + +struct Task { + struct promise_type { + promise_type() = default; + Task get_return_object() { return {}; } + std::suspend_never initial_suspend() { return {}; } + std::suspend_always final_suspend() noexcept { return {}; } + void unhandled_exception() {} + void return_void () {} + awaitable yield_value (int v) { return {v}; } + }; +}; + +Task foo() noexcept { + if (__builtin_constant_p (true ? 1 : co_await awaitable{10})) + PRINT ("const OK"); + else + { + PRINT ("failed : should be const"); + __builtin_abort (); + } + if (__builtin_constant_p (false ? 1 : co_await awaitable{15})) + { + PRINT ("failed : should not be const"); + __builtin_abort (); + } + else + PRINT ("not const, OK"); + if (__builtin_constant_p (5 == (co_yield 42))) + { + PRINT ("failed : should not be const"); + __builtin_abort (); + } + else + PRINT ("not const, OK"); + co_return; +} + +//call foo +int main() { + foo(); +} diff --git a/gcc/testsuite/gcc.dg/pr119160.c b/gcc/testsuite/gcc.dg/pr119160.c index 5743b3b..c3d9b81 100644 --- a/gcc/testsuite/gcc.dg/pr119160.c +++ b/gcc/testsuite/gcc.dg/pr119160.c @@ -4,6 +4,19 @@ typedef __attribute__((__vector_size__ (32))) int V; +/* Add empty implementations of __cyg_profile_func_enter() and + __cyg_profile_func_exit() to avoid problems on non-glibc + systems. */ +void __attribute__((no_instrument_function)) +__cyg_profile_func_enter(void *this_fn, void *call_site) +{ +} + +void __attribute__((no_instrument_function)) +__cyg_profile_func_exit(void *this_fn, void *call_site) +{ +} + void foo (V v, V, V, V *r) { diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c new file mode 100644 index 0000000..875d788 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include <arm_sve.h> + +void +test1 (svbool_t pg, svbool_t x, int *any, svbool_t *ptr) +{ + svbool_t res = svnot_z (pg, x); + *any = svptest_last (pg, res); + *ptr = res; +} + +int +test2 (svbool_t pg, svbool_t x) +{ + svbool_t res = svnot_z (pg, x); + return svptest_first (pg, res); +} + +/* { dg-final { scan-assembler-times {\tnots\t} 2 } } */ +/* { dg-final { scan-assembler-not {\tnot\t} } } */ diff --git a/gcc/testsuite/gcc.target/avr/torture/pr120423-1.c b/gcc/testsuite/gcc.target/avr/torture/pr120423-1.c new file mode 100644 index 0000000..91b4bbc --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr120423-1.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ + +struct data +{ + int a; + int b; + long c; +}; + +unsigned char val; +unsigned val2; + +void func1 (struct data *d) +{ + d->a = 0; + d->b = 0x100 * val - 1; +} + +void func2 (struct data *d) +{ + d->a = 0; + d->c = 0x10000 * val2 - 1; +} + +void func3 (struct data *d) +{ + d->a = 0; + d->c = 0x1000000 * val - 1; +} diff --git a/gcc/testsuite/gcc.target/avr/torture/pr120423-116389.c b/gcc/testsuite/gcc.target/avr/torture/pr120423-116389.c new file mode 100644 index 0000000..928c135 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr120423-116389.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ + +struct T { int val; }; + +void f_int (int); +char* get_pos (void); +struct T* get_pT (void); + +void func (char i) +{ + struct T t = * get_pT (); + unsigned diff = get_pos () - &i; + + if (diff) + { + long val32 = t.val; + if (get_pos ()) + val32 = diff; + if (get_pos ()) + f_int (2 * val32); + } +} diff --git a/gcc/testsuite/gcc.target/avr/torture/pr120423-2.c b/gcc/testsuite/gcc.target/avr/torture/pr120423-2.c new file mode 100644 index 0000000..56e6141 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr120423-2.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ffixed-18 -ffixed-20 -ffixed-22" } */ + +struct data +{ + int a; + int b; + long c; +}; + +unsigned char val; +unsigned val2; + +void func1 (struct data *d) +{ + d->a = 0; + d->b = 0x100 * val - 1; +} + +void func2 (struct data *d) +{ + d->a = 0; + d->c = 0x10000 * val2 - 1; +} + +void func3 (struct data *d) +{ + d->a = 0; + d->c = 0x1000000 * val - 1; +} |